Autor invitado:Derik Hammer (@SQLHammer)
Las diferencias entre TRUNCATE TABLE y DELETE a menudo se malinterpretan. Busco refutar el mito de que TRUNCATE TABLE no se puede deshacer:
Lectura del manual
El artículo de Books Online sobre TRUNCATE TABLE es bastante descriptivo:
“Elimina todas las filas de una tabla o particiones específicas de una tabla, sin registrar las eliminaciones de filas individuales. TRUNCATE TABLE es similar a la instrucción DELETE sin cláusula WHERE; sin embargo, TRUNCATE TABLE es más rápido y utiliza menos recursos del sistema y del registro de transacciones”.El hecho de que TRUNCATE TABLE utilice menos Los recursos del registro de transacciones implican que escribe en el registro de transacciones hasta cierto punto. Averigüemos cuánto e investiguemos su capacidad para revertirse.
Pruébalo
En una publicación anterior, Paul Randal analiza esto en detalle, pero pensé que sería útil proporcionar reproducciones muy simples para refutar ambos elementos de este mito.
¿Se puede revertir TRUNCATE TABLE?
Demostrar que TRUNCATE TABLE se puede revertir es bastante fácil. Simplemente colocaré TRUNCATE TABLE en una transacción y la revertiré.
USE demo; BEGIN TRANSACTION; SELECT COUNT(*) [StartingTableRowCount] FROM [dbo].[Test]; TRUNCATE TABLE [dbo].[Test]; SELECT COUNT(*) [TableRowCountAfterTruncate] FROM [dbo].[Test]; ROLLBACK TRANSACTION; SELECT COUNT(*) [TableRowCountAfterRollback] FROM [dbo].[Test];
Hay 100 000 filas en la tabla y vuelve a 100 000 filas después de la reversión:
¿TRUNCATE TABLE escribe en el registro?
Al ejecutar un CHECKPOINT, obtenemos un punto de partida limpio. Luego podemos verificar los registros antes y después de TRUNCATE TABLE.
USE demo; CHECKPOINT; SELECT COUNT(*) [StartingLogRowCount] FROM sys.fn_dblog (NULL, NULL); TRUNCATE TABLE [dbo].[Test]; SELECT COUNT(*) [LogRowCountAfterTruncate] FROM sys.fn_dblog (NULL, NULL);
Nuestro comando TRUNCATE TABLE generó 237 registros (al menos inicialmente). Esto es lo que nos permite realizar una reversión y cómo SQL Server registra el cambio para empezar.
¿Qué pasa con las ELIMINACIONES?
Si tanto DELETE como TRUNCATE TABLE escriben en el registro y se pueden deshacer, ¿qué los hace diferentes?
Como se mencionó en la referencia de BOL anterior, TRUNCATE TABLE requiere menos recursos del sistema y del registro de transacciones. Ya observamos que se escribieron 237 entradas de registro para el comando TRUNCATE TABLE. Ahora, echemos un vistazo a DELETE.
USE demo; CHECKPOINT; SELECT COUNT(*) [StartingLogRowCount] FROM sys.fn_dblog (NULL, NULL); DELETE FROM [dbo].[Test]; SELECT COUNT(*) [LogRowCountAfterDelete] FROM sys.fn_dblog (NULL, NULL);
Con más de 440 000 registros escritos para DELETE, el comando TRUNCATE es claramente mucho más eficiente.
Resumen
TRUNCATE TABLE es un comando registrado y se puede revertir, con una gran ventaja de rendimiento sobre un DELETE equivalente. DELETE se vuelve importante cuando desea eliminar menos filas de las que existen en la tabla (ya que TRUNCATE TABLE no acepta una cláusula WHERE). Para obtener algunas ideas sobre cómo hacer DELETES más eficientes, consulte la publicación de Aaron Bertrand, "Dividir operaciones de eliminación grandes en partes".