Tengo una gran tabla de datos. Hay 10 millones de registros en esta tabla.
¿Cuál es la mejor manera para esta consulta?
Delete LargeTable where readTime < dateadd(MONTH,-7,GETDATE())
sql-server
sql-server-2008
sql-optimization
usuario3107343
fuente
fuente
Respuestas:
Si está eliminando todas las filas de esa tabla, la opción más simple es Truncar la tabla, algo así como
Truncar la tabla simplemente vaciará la tabla, no puede usar la cláusula WHERE para limitar las filas que se eliminarán y no se dispararán desencadenantes.
Por otro lado, si está eliminando más del 80-90 por ciento de los datos, diga que si tiene un total de 11 millones de filas y desea eliminar 10 millones, otra forma sería insertar estos 1 millón de filas (registros que desea mantener ) a otra tabla de etapas. Trunca esta tabla grande e inserta de nuevo estas 1 millón de filas.
O si los permisos / vistas u otros objetos que tienen esta tabla grande como su tabla subyacente no se ven afectados al soltar esta tabla, puede obtener esta cantidad relativamente pequeña de las filas en otra tabla, soltar esta tabla y crear otra tabla con el mismo esquema e importarlos filas de nuevo en esta tabla ex-Large.
Una última opción que se me ocurre es cambiar la base de datos
Recovery Mode to SIMPLE
y luego eliminar filas en lotes más pequeños usando un ciclo while algo como esto ...y no olvide volver a cambiar el modo de Recuperación a completo y creo que debe hacer una copia de seguridad para que sea completamente efectivo (los modos de cambio o recuperación).
fuente
optimal solution for unknown case
ese es el sueño, ¿no? Lamentablemente, no puede curar todas las enfermedades con una sola píldora; He sugerido algunas posibles soluciones para diferentes escenarios. Desafortunadamente, no hay una bala de astilla aquí.La respuesta de @ m-ali es correcta, pero también tenga en cuenta que los registros podrían crecer mucho si no confirma la transacción después de cada fragmento y realiza un punto de control. Así es como lo haría y tomaría este artículo http://sqlperformance.com/2013/03/io-subsystem/chunk-deletes como referencia, con pruebas de rendimiento y gráficos:
fuente
COMMIT TRANSACTION
yCHECKPOINT
los registros siguen creciendo. Gracias por dejar esto claro.@Deleted_Rows
con 10000 o puede terminar con un bucle infinito debido a que elimina indefinidamente pequeños conjuntos de datos. EntoncesWHILE (@Deleted_Rows = 10000)
, tan pronto como no haya una "página" completa de datos para eliminar, se detendrá. En su implementación,WHILE (@Deleted_Rows > 0)
el ciclo while se ejecutará nuevamente incluso si solo eliminó una fila, y la próxima ejecución también podría encontrar una o dos filas para eliminar, lo que da como resultado un ciclo infinito.WHILE
propio bucle:dateadd(MONTH,-7,GETDATE())
.WHILE
bucle.También puede usar GO + cuántas veces desea ejecutar la misma consulta.
fuente
GO xx
supone que esta sintaxis funciona? Me sale un "no se encontró el procedimiento almacenado ''" error. SinGO
embargo, sin el comando funciona bien.@Francisco Goldenstein, solo una pequeña corrección. El COMMIT debe usarse después de establecer la variable; de lo contrario, WHILE se ejecutará solo una vez:
fuente
Esta variación de M. Ali está funcionando bien para mí. Elimina algunos, borra el registro y se repite. Estoy viendo el registro crecer, caer y comenzar de nuevo.
fuente
# of rows
eliminación a la vez, y también laWHERE
cláusula. ¡Funciona de maravilla!Si está dispuesto (y puede) implementar la partición, esa es una técnica efectiva para eliminar grandes cantidades de datos con poca sobrecarga de tiempo de ejecución. Sin embargo, no es rentable para un ejercicio único.
fuente
Pude eliminar 19 millones de filas de mi tabla de 21 millones de filas en cuestión de minutos . Aquí está mi enfoque.
Si tiene una clave primaria de incremento automático en esta tabla, puede utilizar esta clave primaria.
Obtenga el valor mínimo de la clave primaria de la tabla grande donde readTime <dateadd (MONTH, -7, GETDATE ()). (Agregue índice en readTime, si aún no está presente, este índice se eliminará de todos modos junto con la tabla en el paso 3.). Vamos a almacenarlo en una variable 'min_primary'
Inserte todas las filas que tienen la clave primaria> min_primary en una tabla de preparación (tabla de memoria si el número de filas no es grande).
Suelta la mesa grande.
Recrea la mesa. Copie todas las filas de la tabla de etapas a la tabla principal.
Suelta la mesa de ensayo.
fuente
Puede eliminar lotes pequeños usando un ciclo while, algo como esto:
fuente
Otro uso:
Opcional;
Si el registro de transacciones está habilitado, deshabilite los registros de transacciones.
fuente
Sintaxis más corta
fuente
Si está utilizando SQL Server 2016 o superior y si su tabla tiene particiones creadas en función de la columna que está tratando de eliminar (por ejemplo, la columna Timestamp), puede usar este nuevo comando para eliminar datos por particiones.
TABLA TRUNCADA CON (PARTICIONES ({|} [, ... n]))
Esto eliminará los datos solo en la (s) partición (es) seleccionada (s) y debería ser la forma más eficiente de eliminar datos de una parte de la tabla, ya que no creará registros de transacciones y se realizará tan rápido como el truncamiento normal pero sin que se eliminen todos los datos. de la mesa.
El inconveniente es que si su tabla no está configurada con partición, entonces necesita ir a la vieja escuela y eliminar los datos con un enfoque regular y luego volver a crear la tabla con particiones para que pueda hacer esto en el futuro, que es lo que hice. Agregué la creación y eliminación de particiones en el procedimiento de inserción. Tenía una tabla con 500 millones de filas, por lo que esta era la única opción para reducir el tiempo de eliminación.
Para obtener más detalles, consulte los siguientes enlaces: https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-2017
Tabla truncada de SQL Server 2016 con particiones
A continuación se muestra lo que hice primero para eliminar los datos antes de poder volver a crear la tabla con particiones con los datos requeridos. Esta consulta se ejecutará durante días durante la ventana de tiempo especificada hasta que se eliminen los datos.
fuente
Si digo sin bucle, puedo usar la
GOTO
instrucción para eliminar una gran cantidad de registros usando el servidor SQL. exa.De esta manera, puede eliminar una gran cantidad de datos con un tamaño de eliminación más pequeño.
avíseme si requiere más información.
fuente