Autor gościnny:Derik Hammer (@SQLHammer)
Różnice między TRUNCATE TABLE i DELETE są często źle rozumiane. Staram się obalić mit, że OBCIĄŻENIE TABELI nie może zostać wycofane:
Czytanie instrukcji
Artykuł Books Online na temat TRUNCATE TABLE jest dość opisowy:
„Usuwa wszystkie wiersze z tabeli lub określonych partycji tabeli, bez rejestrowania usunięcia poszczególnych wierszy. TRUNCATE TABLE jest podobna do instrukcji DELETE bez klauzuli WHERE; jednak TRUNCATE TABLE jest szybszy i zużywa mniej zasobów systemowych i dzienników transakcji”.Fakt, że TRUNCATE TABLE używa mniej Zasoby dziennika transakcji oznaczają, że do pewnego stopnia zapisuje w dzienniku transakcji. Dowiedzmy się, ile i zbadajmy możliwość wycofania.
Udowodnij to
We wcześniejszym poście Paul Randal omawia to ze drobiazgami, ale pomyślałem, że przydatne będzie przedstawienie bardzo prostych powtórzeń, aby obalić oba elementy tego mitu.
Czy można wycofać OBCIĄŻENIE TABELI?
Udowodnienie, że TRUNCATE TABLE można cofnąć, jest dość łatwe. Po prostu wstawię TRUNCATE TABLE do transakcji i wycofam ją.
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];
W tabeli jest 100 000 wierszy, a po wycofaniu wraca do 100 000 wierszy:
Czy TRUNCATE TABLE zapisuje do dziennika?
Wykonując CHECKPOINT otrzymujemy czysty punkt wyjścia. Następnie możemy sprawdzić zapisy dziennika przed i po tabeli 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);
Nasze polecenie TRUNCATE TABLE wygenerowało 237 rekordów dziennika (przynajmniej początkowo). To pozwala nam na wycofanie zmian i jak SQL Server rejestruje zmianę na początku.
A co z USUWANIEM?
Jeśli zarówno DELETE, jak i TRUNCATE TABLE zapisują w dzienniku i można je cofnąć, co je różni?
Jak wspomniano w powyższym odwołaniu BOL, TRUNCATE TABLE zajmuje mniej zasobów systemowych i dzienników transakcji. Zaobserwowaliśmy już, że dla polecenia TRUNCATE TABLE zapisano 237 rekordów dziennika. Teraz spójrzmy na 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);
Z ponad 440 000 rekordów dziennika zapisanych dla polecenia DELETE, polecenie TRUNCATE jest wyraźnie znacznie wydajniejsze.
Podsumowanie
TRUNCATE TABLE to polecenie zarejestrowane i można je wycofać, co zapewnia ogromną przewagę wydajności nad równoważnym poleceniem DELETE. DELETE staje się ważne, gdy chcesz usunąć mniej wierszy niż istnieje w tabeli (ponieważ TRUNCATE TABLE nie akceptuje klauzuli WHERE). Aby uzyskać więcej pomysłów na zwiększenie wydajności DELETE, zobacz post Aarona Bertranda „Rozbijaj duże operacje usuwania na porcje”.