Database
 sql >> Database >  >> RDS >> Database

Miti sulle prestazioni:il troncamento non può essere ripristinato

Autore ospite:Derik Hammer (@SQLHammer)


Le differenze tra TRUNCATE TABLE e DELETE sono spesso fraintese. Cerco di smentire il mito secondo cui TRUNCATE TABLE non può essere ripristinato:

“TRUNCATE TABLE non è registrato e quindi non può essere ripristinato. Devi usare DELETE, se in una transazione."

Lettura del manuale

L'articolo della documentazione in linea su TRUNCATE TABLE è abbastanza descrittivo:

“Rimuove tutte le righe da una tabella o le partizioni specificate di una tabella, senza registrare le singole eliminazioni di riga. TRUNCATE TABLE è simile all'istruzione DELETE senza alcuna clausola WHERE; tuttavia, TRUNCATE TABLE è più veloce e utilizza meno risorse del registro delle transazioni e del sistema.

Il fatto che TRUNCATE TABLE ne usi meno le risorse del registro delle transazioni implicano che scrivano nel registro delle transazioni in una certa misura. Scopriamo quanto e indaghiamo sulla sua capacità di essere ripristinato.

Dimostralo

In un post precedente, Paul Randal lo esamina in modo meticoloso, ma ho pensato che sarebbe stato utile fornire repliche molto semplici per smentire entrambi gli elementi di questo mito.

È possibile ripristinare TRUNCATE TABLE?

Dimostrare che TRUNCATE TABLE può essere ripristinato è abbastanza facile. Metterò semplicemente TRUNCATE TABLE in una transazione e la annullerò.

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];

Ci sono 100.000 righe nella tabella e ritorna a 100.000 righe dopo il rollback:

TRUNCATE TABLE scrive nel registro?

Eseguendo un CHECKPOINT, otteniamo un punto di partenza pulito. Quindi possiamo controllare i record di registro prima e dopo il 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);

Il nostro comando TRUNCATE TABLE ha generato 237 record di registro (almeno inizialmente). Questo è ciò che ci consente di eseguire un rollback e come SQL Server registra la modifica per cominciare.

E i DELETE?

Se sia DELETE che TRUNCATE TABLE scrivono nel registro e possono essere ripristinati, cosa li rende diversi?

Come menzionato nel riferimento BOL sopra, TRUNCATE TABLE richiede meno risorse del registro delle transazioni e del sistema. Abbiamo già osservato che 237 record di registro sono stati scritti per il comando TRUNCATE TABLE. Ora, diamo un'occhiata 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 oltre 440.000 record di registro scritti per DELETE, il comando TRUNCATE è chiaramente molto più efficiente.

Concludi

TRUNCATE TABLE è un comando registrato e può essere ripristinato, con un enorme vantaggio in termini di prestazioni rispetto a un DELETE equivalente. DELETE diventa importante quando si desidera eliminare un numero di righe inferiore a quello esistente nella tabella (poiché TRUNCATE TABLE non accetta una clausola WHERE). Per alcune idee su come rendere più efficienti le DELETE, consulta il post di Aaron Bertrand, "Scomponi le operazioni di eliminazione di grandi dimensioni in blocchi".

Informazioni sull'autore

Derik è un professionista dei dati e un MVP Microsoft Data Platform appena coniato incentrato su SQL Server. La sua passione si concentra sull'elevata disponibilità, sul ripristino di emergenza, sull'integrazione continua e sulla manutenzione automatizzata. La sua esperienza ha abbracciato l'amministrazione di database a lungo termine, la consulenza e le iniziative imprenditoriali che lavorano nei settori finanziario e sanitario. Attualmente è un Senior Database Administrator responsabile del team Database Operations presso Subway Franchise World Headquarters. Quando non è in orario o non sta scrivendo su SQLHammer.com, Derik dedica il suo tempo alla famiglia #sql come Chapter Leader per il gruppo di utenti di FairfieldPASS SQL Server a Stamford, CT.