2011-12-29 21 views
7

¿Qué límite debe colocarse en el número de filas para eliminar en una instrucción SQL?SQL DELETE - Número máximo de filas

Tenemos que eliminar de 1 a varios cientos de miles de filas y necesitamos aplicar algún tipo de límite de mejores prácticas para no matar completamente al servidor SQL o llenar los registros cada vez que vacíemos una papelera.

Esta pregunta no es específica de ningún tipo de base de datos.

+0

No se puede responder a esta pregunta vaga. No hay una bala de plata – zerkms

+0

Utilizamos el trabajo por lotes del movimiento nocturno para mover registros de una tabla a otra. Ejecutamos lotes de 10.000 y el rendimiento alcanzado es insignificante. – Dimitri

+0

Deberá intentar agregar algunos límites y controlar el rendimiento del servidor para obtener la mejor respuesta. – piotrekkr

Respuesta

12

Esa es una pregunta muy amplia que básicamente se reduce a "depende". Los factores que la influyen incluyen:

  • ¿Cuál es su nivel de concurrencia? Una instrucción delete coloca un bloqueo exclusivo en las filas afectadas. Dependiendo del motor de la base de datos, la distribución de datos eliminados, etc., que podría escalar a la página o tabla completa. ¿Pueden permitirse que sus lectores de datos se bloqueen durante la eliminación?

  • ¿Cuán compleja es la declaración de eliminación? ¿A cuántas otras mesas se está sumando, o hay cláusulas WHERE complejas? A veces la identificación de las filas para eliminar puede ser más "costosa" que la eliminación en sí misma, por lo que una gran eliminación puede ser "más barata".

  • ¿Tiene miedo a los interbloqueos? A medida que disminuye el tamaño de su eliminación, se reduce la "huella" de interbloqueo. Idealmente, las eliminaciones de una sola fila siempre tendrán éxito.

  • ¿Le preocupa el rendimiento? Al igual que con cualquier instrucción SQL, hay una cantidad generalmente constante de sobrecarga (cosas de conexión, análisis de consultas, resultados de devolución, etc.). Desde un punto de vista de conexión única, una eliminación de 1000 líneas será más rápida que 1000 x eliminaciones de 1 línea.

  • No se olvide de gastos indirectos de mantenimiento de índice, limpieza de fragmentación o cualquier desencadenante. También pueden afectar tu sistema.

En general, sin embargo, comparo en 1000 líneas por extracto. La mayoría de los sistemas con los que he trabajado (sub-"empresa") terminan con un punto óptimo entre 500 y 5000 registros por eliminación. Me gustaría hacer algo como esto:

set rowcount 500 

select 1 -- Just to force @@rowcount > 0 
while @@ROWCOUNT > 0 
delete from [table] 
    [where ...] 
+0

+1, agregaría que si está eliminando una cierta cantidad de filas, a veces es mejor hacerlo; así que elimine 10 y luego 100 y 1.000, ya que el DB ha almacenado parte del trabajo en caché, lo que encaja con su punto 4. – Ben

+0

Por lo general, tiene MUCHO más código de apoyo para hacer cualquier cosa que no sea una subida "ficticia". También descubrí que intentar hacer un borrado de "máximas" filas/segundos es bastante inútil. Un mejor enfoque es encontrar una ventana aceptable (digamos 15 segundos) e intentar eliminar tantas filas a la vez. En pseudo código de comentario: elija 100 filas para eliminar. Eliminar y obtener información de tiempo. Si el tiempo es <15 segundos, seleccione ROWS * 1.5 para eliminar; de lo contrario, elija filas * 0.5 para eliminar. Repetir. Esto aumentará su rendimiento basado en el tiempo y es sensible a otras actividades en la base de datos. – jklemmack

+0

Para futuros lectores, consulte la respuesta de @SQLPhil a continuación. Con base en Microsoft Books Online, una versión futura de SQL Server NO respetará 'SET ROWCOUNT' para las sentencias' INSERT', 'UPDATE', o' DELETE'. Lo mejor es usar la sintaxis 'TOP' en su lugar. – jklemmack

0

una respuesta general es eliminar la tabla y volver a crearlo, es una buena solución de rendimiento, sino que se aplica para la tabla completa

+0

y ¿qué ocurre si hay procedimientos, funciones, vistas, etc. que dependen de la tabla que está eliminando? Los invalidarás sin ningún motivo justificado. – Ben

1

A menos que tenga una gran cantidad de factores desencadenantes o restricciones de integridad para verificar, eliminación shouldn No será una operación tan costosa.

Pero si le preocupa el rendimiento, mi corazonada inicial sería marcar las filas apropiadas como eliminadas y luego eliminarlas físicamente más tarde durante una limpieza periódica. Pero no soy un gran admirador de esto porque tendrás que cambiar las consultas en esa tabla para excluir filas lógicamente, pero no físicamente eliminadas.

1

Cada vez que veo una base de datos que elimina de manera rutinaria grandes cantidades de filas a granel, que me hace pensar que el modelo de datos o el diseño de procesamiento no es óptima. ¿Por qué cargar 1 millón de filas y luego eliminarlas? Si necesita hacer algo como purgar datos históricos, entonces considere la partición de la tabla.

+1

Russel. Puede haber razones por las cuales cargaría un millón de registros; De esta manera desea realizar cálculos y almacenar los valores calculados antes de descartar los datos brutos. Pero si tiene un buen punto, el diseño adecuado es importante. – Leons

4

Aunque limitar el número de filas afectadas por su eliminación usando la opción set rowcount y luego realizar un bucle es muy bueno (y lo he usado muchas veces), tenga en cuenta que desde SQL 2012 en adelante esto no ser una opción (ver BOL).

Por lo tanto, otra opción puede ser limitar el número de filas que se eliminan utilizando la cláusula TOP. es decir,

SELECT 1 

WHILE @@ROWCOUNT > 0 
BEGIN 
    DELETE TOP (#) 
    FROM mytable 
    [WHERE ...] 
END 
Cuestiones relacionadas