Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Excluindo 1 milhão de linhas no SQL Server


Aqui está uma estrutura para uma exclusão em lote, conforme sugerido acima. Não tente 1M de uma vez...

O tamanho do lote e o atraso de espera são obviamente bastante variáveis ​​e dependeriam dos recursos de seus servidores, bem como da sua necessidade de mitigar a contenção. Pode ser necessário excluir manualmente algumas linhas, medindo quanto tempo elas demoram e ajustar o tamanho do lote para algo que seu servidor possa manipular. Como mencionado acima, qualquer coisa acima de 5000 pode causar bloqueio (que eu não sabia).

Isso seria melhor feito depois de horas... mas 1 milhão de linhas não é muito para o SQL manipular. Se você assistir suas mensagens no SSMS, pode demorar um pouco para a saída de impressão ser exibida, mas ela será exibida após vários lotes, mas lembre-se de que não será atualizado em tempo real.

Editar:Adicionado um tempo de parada @MAXRUNTIME &@BSTOPATMAXTIME . Se você definir @BSTOPATMAXTIME para 1, o script irá parar por conta própria no horário desejado, digamos 8h00. Dessa forma, você pode agendar todas as noites para começar à meia-noite e parar antes da produção às 8h.

Edit:A resposta é bastante popular, então adicionei o RAISERROR em vez de PRINT por comentários.
DECLARE @BATCHSIZE INT, @WAITFORVAL VARCHAR(8), @ITERATION INT, @TOTALROWS INT, @MAXRUNTIME VARCHAR(8), @BSTOPATMAXTIME BIT, @MSG VARCHAR(500)
SET DEADLOCK_PRIORITY LOW;
SET @BATCHSIZE = 4000
SET @WAITFORVAL = '00:00:10'
SET @MAXRUNTIME = '08:00:00' -- 8AM
SET @BSTOPATMAXTIME = 1 -- ENFORCE 8AM STOP TIME
SET @ITERATION = 0 -- LEAVE THIS
SET @TOTALROWS = 0 -- LEAVE THIS

WHILE @BATCHSIZE>0
BEGIN
    -- IF @BSTOPATMAXTIME = 1, THEN WE'LL STOP THE WHOLE JOB AT A SET TIME...
    IF CONVERT(VARCHAR(8),GETDATE(),108) >= @MAXRUNTIME AND @BSTOPATMAXTIME=1
    BEGIN
        RETURN
    END

    DELETE TOP(@BATCHSIZE)
    FROM SOMETABLE
    WHERE 1=2

    SET @[email protected]@ROWCOUNT
    SET @[email protected]+1
    SET @[email protected][email protected]
    SET @MSG = 'Iteration: ' + CAST(@ITERATION AS VARCHAR) + ' Total deletes:' + CAST(@TOTALROWS AS VARCHAR)
    RAISERROR (@MSG, 0, 1) WITH NOWAIT
    WAITFOR DELAY @WAITFORVAL 
END