sql >> Base de Datos >  >> RDS >> Sqlserver

Eliminando 1 millón de filas en SQL Server

Aquí hay una estructura para una eliminación por lotes como se sugirió anteriormente. No intentes 1M a la vez...

El tamaño del lote y el retraso de la espera son obviamente bastante variables y dependerán de las capacidades de sus servidores, así como de su necesidad de mitigar la contención. Es posible que deba eliminar manualmente algunas filas, medir el tiempo que tardan y ajustar el tamaño de su lote a algo que su servidor pueda manejar. Como se mencionó anteriormente, cualquier valor superior a 5000 puede provocar un bloqueo (que yo no conocía).

Esto se haría mejor después de horas... pero 1 millón de filas realmente no es mucho para que lo maneje SQL. Si observa sus mensajes en SSMS, es posible que la salida de impresión tarde un poco en mostrarse, pero lo hará después de varios lotes, solo tenga en cuenta que no se actualizará en tiempo real.

Editar:se agregó un tiempo de parada @MAXRUNTIME &@BSTOPATMAXTIME . Si configura @BSTOPATMAXTIME a 1, la secuencia de comandos se detendrá por sí sola a la hora deseada, por ejemplo, a las 8:00 a. m. De esta manera, puede programarlo todas las noches para que comience, digamos, a la medianoche y se detenga antes de la producción a las 8 a.m.

Editar:la respuesta es bastante popular, por lo que he agregado el RAISERROR en lugar de PRINT por comentarios.

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