sql >> Base de Datos >  >> RDS >> Database

Mitos de rendimiento:Truncar no se puede deshacer

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:

“TRUNCATE TABLE no se registra y, por lo tanto, no se puede revertir. Tienes que usar DELETE, si estás en una transacción.”

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".

Sobre el autor

Derik es un profesional de datos y recientemente nombrado MVP de Microsoft Data Platform que se enfoca en SQL Server. Su pasión se centra en la alta disponibilidad, la recuperación ante desastres, la integración continua y el mantenimiento automatizado. Su experiencia ha abarcado la administración de bases de datos a largo plazo, la consultoría y las empresas empresariales que trabajan en las industrias financiera y de atención médica. Actualmente es administrador sénior de bases de datos a cargo del equipo de operaciones de bases de datos en la sede mundial de franquicias de Subway. Cuando no está trabajando o blogueando en SQLHammer.com, Derik dedica su tiempo a la familia #sql como líder del capítulo del grupo de usuarios de FairfieldPASS SQL Server en Stamford, CT.