sql >> Database >  >> RDS >> Database

Prestatiemythen:Truncate kan niet worden teruggedraaid

Gastauteur:Derik Hammer (@SQLHammer)


De verschillen tussen TRUNCATE TABLE en DELETE worden vaak verkeerd begrepen. Ik probeer de mythe te weerleggen dat TRUNCATE TABLE niet kan worden teruggedraaid:

“TRUNCATE TABLE is niet gelogd en kan daarom niet worden teruggedraaid. U moet DELETE gebruiken als u in een transactie bent.

De handleiding lezen

Het Books Online-artikel over TRUNCATE TABLE is redelijk beschrijvend:

“Verwijdert alle rijen uit een tabel of gespecificeerde partities van een tabel, zonder de individuele rijverwijderingen vast te leggen. TRUNCATE TABLE lijkt op de DELETE-instructie zonder WHERE-clausule; TRUNCATE TABLE is echter sneller en gebruikt minder systeem- en transactielogboekbronnen.”

Het feit dat TRUNCATE TABLE minder . gebruikt transactielogboekbronnen houdt in dat het tot op zekere hoogte naar het transactielogboek schrijft. Laten we eens kijken hoeveel en onderzoeken of het kan worden teruggedraaid.

Bewijs het

In een eerdere post gaat Paul Randal hier minutieus op in, maar ik dacht dat het nuttig zou zijn om heel eenvoudige herhalingen te geven om beide elementen van deze mythe te weerleggen.

Kan TRUNCATE TABLE worden teruggedraaid?

Bewijzen dat TRUNCATE TABLE kan worden teruggedraaid, is eenvoudig genoeg. Ik zal gewoon TRUNCATE TABLE in een transactie plaatsen en het terugdraaien.

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

Er zijn 100.000 rijen in de tabel en deze keert terug naar 100.000 rijen na het terugdraaien:

Schrijft TRUNCATE TABLE naar het logboek?

Door een CHECKPOINT uit te voeren, krijgen we een schoon startpunt. Dan kunnen we de logrecords voor en na de TRUNCATE TABLE controleren.

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

Ons TRUNCATE TABLE-commando genereerde 237 logrecords (tenminste aanvankelijk). Dit is wat ons in staat stelt om een ​​rollback uit te voeren, en hoe SQL Server de wijziging registreert om mee te beginnen.

Hoe zit het met VERWIJDEREN?

Als zowel DELETE als TRUNCATE TABLE naar het logboek schrijven en teruggedraaid kunnen worden, wat maakt ze dan anders?

Zoals vermeld in de BOL-referentie hierboven, neemt TRUNCATE TABLE minder systeem- en transactielogboekbronnen in beslag. We zagen al dat er 237 logrecords zijn geschreven voor het TRUNCATE TABLE-commando. Laten we nu eens kijken naar de VERWIJDEREN.

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

Met meer dan 440.000 logrecords geschreven voor DELETE, is het TRUNCATE-commando duidelijk veel efficiënter.

Afronding

TRUNCATE TABLE is een gelogde opdracht en kan worden teruggedraaid, met een enorm prestatievoordeel ten opzichte van een gelijkwaardige DELETE. DELETE wordt belangrijk wanneer u minder rijen wilt verwijderen dan er in de tabel staan ​​(aangezien TRUNCATE TABLE geen WHERE-clausule accepteert). Voor enkele ideeën over het efficiënter maken van VERWIJDEREN, zie het bericht van Aaron Bertrand, "Breek grote verwijderingsbewerkingen in stukken."

Over de auteur

Derik is een dataprofessional en een nieuwe Microsoft Data Platform MVP die zich richt op SQL Server. Zijn passie ligt bij hoge beschikbaarheid, noodherstel, continue integratie en geautomatiseerd onderhoud. Zijn ervaring strekt zich uit over databasebeheer op lange termijn, consultancy en ondernemende ondernemingen in de financiële sector en de gezondheidszorg. Momenteel is hij Senior Database Administrator en heeft hij de leiding over het Database Operations-team op het Subway Franchise World Headquarters. Als hij niet aan het werk is of blogt op SQLHammer.com, wijdt Derik zijn tijd aan de #sqlfamily als hoofdstukleider voor de FairfieldPASS SQL Server-gebruikersgroep in Stamford, CT.
  1. ondersteunt rails postgres adapter ssl?

  2. Pleidooi voor IN PLAATS VAN Triggers - Deel 1

  3. PostgreSQL-databaseservice

  4. Bepaal Oracle null ==null