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