Gæsteforfatter:Derik Hammer (@SQLHammer)
Forskellene mellem TRUNCATE TABLE og DELETE bliver ofte misforstået. Jeg søger at modbevise myten om, at TRUNCATE TABLE ikke kan rulles tilbage:
Læsning af manualen
Books Online-artiklen om TRUNCATE TABLE er ret beskrivende:
"Fjerner alle rækker fra en tabel eller specificerede partitioner i en tabel uden at logge de enkelte rækkesletninger. TRUNCATE TABLE ligner DELETE-sætningen uden WHERE-sætning; TRUNCATE TABLE er dog hurtigere og bruger færre system- og transaktionslogressourcer."Det faktum, at TRUNCATE TABLE bruger færre transaktionslogressourcer indebærer, at den skriver til transaktionsloggen til en vis grad. Lad os finde ud af hvor meget og undersøge dets evne til at blive rullet tilbage.
Bevis det
I et tidligere indlæg gennemgår Paul Randal dette omhyggeligt, men jeg tænkte, at det ville være nyttigt at give meget simple repros for at modbevise begge elementer i denne myte.
Kan TRUNCATE TABLE rulles tilbage?
Det er nemt nok at bevise, at TRUNCATE TABLE kan rulles tilbage. Jeg vil simpelthen sætte TRUNCATE TABLE i en transaktion og rulle den tilbage.
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];
Der er 100.000 rækker i tabellen, og den vender tilbage til 100.000 rækker efter tilbagerulning:
Skriver TRUNCATE TABLE til loggen?
Ved at udføre et CHECKPOINT får vi et rent udgangspunkt. Så kan vi kontrollere logposterne før og efter 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);
Vores TRUNCATE TABLE-kommando genererede 237 logposter (i det mindste i begyndelsen). Det er det, der gør os i stand til at udføre en tilbagerulning, og hvordan SQL Server registrerer ændringen til at begynde med.
Hvad med DELETEs?
Hvis både DELETE og TRUNCATE TABLE skriver til loggen og kan rulles tilbage, hvad gør dem så anderledes?
Som nævnt i BOL-referencen ovenfor, tager TRUNCATE TABLE færre system- og transaktionslogressourcer. Vi har allerede observeret, at 237 logposter blev skrevet til TRUNCATE TABLE-kommandoen. Lad os nu se på 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);
Med over 440.000 logposter skrevet til DELETE, er TRUNCATE-kommandoen klart meget mere effektiv.
Afslutning
TRUNCATE TABLE er en logget kommando og kan rulles tilbage, med en kæmpe fordel i forhold til en tilsvarende DELETE. DELETE bliver vigtigt, når du ønsker at slette færre rækker, end der findes i tabellen (da TRUNCATE TABLE ikke accepterer en WHERE-sætning). For nogle ideer til at gøre DELETEs mere effektive, se Aaron Bertrands indlæg, "Opdel store sletningsoperationer i bidder."