DELETE vs TRUNCATE

35

Próbuję lepiej zrozumieć różnice między poleceniami DELETEi TRUNCATE. Moje rozumienie elementów wewnętrznych przebiega w następujący sposób:

DELETE-> aparat bazy danych znajduje i usuwa wiersz z odpowiednich stron danych i wszystkich stron indeksu, w których wiersz jest wprowadzony. Im więcej indeksów, tym dłużej trwa usuwanie.

TRUNCATE -> po prostu masowo usuwa wszystkie strony danych tabeli, dzięki czemu jest to bardziej wydajna opcja usuwania zawartości tabeli.

Zakładając, że powyższe jest poprawne (popraw mnie, jeśli nie):

  1. Jak różne tryby odzyskiwania wpływają na każdą instrukcję? Jeśli w ogóle jest jakikolwiek efekt
  2. Czy podczas usuwania skanowane są wszystkie indeksy, czy tylko te, w których znajduje się wiersz? Zakładam, że wszystkie indeksy są skanowane (a nie wyszukiwane?)
  3. Jak replikowane są polecenia? Czy polecenie SQL jest wysyłane i przetwarzane dla każdego subskrybenta? A może MSSQL jest nieco bardziej inteligentny?
Stuart Blackler
źródło
2
Istnieje kilka powiązanych informacji na temat DELETEi TRUNCATEw odpowiedziach na to pytanie na temat użyteczności TRUNCATE-ing bezpośrednio przed DROP. Możesz także samodzielnie przekopać się w dzienniku, aby zbadać efekty obu poleceń, korzystając z techniki opisanej w tej odpowiedzi .
Nick Chammas
1
Ta odpowiedź pokazuje elementy wewnętrzne operacji DELETE i TRUNCATE. Pytanie pokazuje także szczególną sytuację, w której TRUNCATE działa lepiej.
孔夫子
5
@idstam TRUNCATEmożna przywrócić. Nick opisuje to w swojej odpowiedzi na pytanie, które podał .
Mark Storey-Smith,
Obcinanie wymaga uprawnienia do „zmiany tabeli” (w tym sensie, że obcinanie jest wtyczką zastępującą usuwanie).
crokusek

Odpowiedzi:

58

DELETE -> aparat bazy danych znajduje i usuwa wiersz z odpowiednich stron danych i wszystkich stron indeksu, w których wiersz jest wprowadzony. Im więcej indeksów, tym dłużej trwa usuwanie.

Tak, choć są tutaj dwie opcje. Wiersze mogą być usuwane z indeksów nieklastrowanych wiersz po rzędzie przez tego samego operatora, który wykonuje usuwanie tabeli podstawowej. Jest to znane jako wąski (lub na wiersz) plan aktualizacji:

Usunięcie wiersza

Lub skasowanie indeksu nieklastrowanego może być wykonane przez oddzielnych operatorów, po jednym na indeks nieklastrowany. W takim przypadku (zwany planem aktualizacji szerokim lub według indeksu) pełny zestaw akcji jest przechowywany w tabeli roboczej (chętny bufor) przed odtworzeniem raz na indeks, często jawnie posortowany według poszczególnych kluczy indeksu nieklastrowanego, aby zachęcić do sekwencyjnego wzór dostępu.

Po usunięciu indeksu

TRUNCATE -> po prostu masowo usuwa wszystkie strony danych tabeli, dzięki czemu jest to bardziej wydajna opcja usuwania zawartości tabeli.

Tak. TRUNCATE TABLEjest bardziej wydajny z wielu powodów:

  1. Może być potrzebnych mniej blokad. Obcinanie zwykle wymaga tylko pojedynczej blokady modyfikacji schematu na poziomie tabeli (i wyłącznych blokad w każdym stopniu zwolnionych). Usunięcie może uzyskać blokady o niższym stopniu szczegółowości (wiersza lub strony), a także blokad wyłącznych na wszystkich zwolnionych stronach .
  2. Tylko obcięcie gwarantuje, że wszystkie strony są zwolnione z tabeli sterty. Usunięcie może pozostawić puste strony w stercie, nawet jeśli określono wyłączną wskazówkę dotyczącą blokowania tabeli (na przykład, jeśli dla bazy danych jest włączony poziom izolacji wersji wiersza).
  3. Obcinanie jest zawsze rejestrowane minimalnie (niezależnie od używanego modelu odzyskiwania). W dzienniku transakcji rejestrowane są tylko operacje zwolnienia strony.
  4. Obcinanie może korzystać z odroczonego upuszczania, jeśli obiekt ma rozmiar 128 lub większy. Odroczone upuszczenie oznacza, że ​​faktyczna praca przydziałów jest wykonywana asynchronicznie przez wątek serwera w tle.

Jak różne tryby odzyskiwania wpływają na każdą instrukcję? Czy w ogóle jest jakiś efekt?

Usunięcie jest zawsze w pełni rejestrowane (każdy usunięty wiersz jest zapisywany w dzienniku transakcji). Istnieją niewielkie różnice w zawartości rekordów dziennika, jeśli model odzyskiwania jest inny niż FULL, ale nadal jest to technicznie pełne rejestrowanie.

Czy podczas usuwania skanowane są wszystkie indeksy, czy tylko te, w których znajduje się wiersz? Zakładam, że wszystkie indeksy są skanowane (a nie wyszukiwane?)

Usunięcie wiersza w indeksie (przy użyciu wcześniej przedstawionych wąskich lub szerokich planów aktualizacji) jest zawsze kluczem (wyszukiwanie). Skanowanie całego indeksu dla każdego usuniętego wiersza byłoby strasznie nieefektywne. Spójrzmy jeszcze raz na plan aktualizacji dla indeksu pokazany wcześniej:

Szeroki plan 2

Plany wykonania są potokami zależnymi od zapotrzebowania: operatorzy nadrzędni (po lewej) napędzają operatorów podrzędnych do wykonania pracy, żądając od nich pojedynczych wierszy. Operatory sortowania blokują (muszą zużyć całe dane wejściowe przed utworzeniem pierwszego posortowanego wiersza), ale nadal są sterowane przez swojego rodzica (usuwanie indeksu) żądającego pierwszego wiersza. Usuwanie indeksu wyciąga wiersz po zakończeniu sortowania, aktualizując docelowy indeks nieklastrowany dla każdego wiersza.

W szerokim planie aktualizacji często zobaczysz kolumny dodawane do strumienia wierszy przez operatora aktualizacji tabeli podstawowej. W takim przypadku Clustered Index Delete dodaje do strumienia nieklastrowane kolumny kluczy indeksu. Te dane są wymagane przez silnik pamięci masowej do zlokalizowania wiersza do usunięcia z indeksu nieklastrowanego:

Szczegóły listy wyników

Jak replikowane są polecenia? Czy polecenie SQL jest wysyłane i przetwarzane dla każdego subskrybenta? A może SQL Server jest nieco bardziej inteligentny?

Obcinanie nie jest dozwolone w tabeli publikowanej przy użyciu replikacji transakcyjnej lub scalającej. Sposób replikacji usunięć zależy od typu replikacji i sposobu jej konfiguracji. Na przykład replikacja migawki po prostu replikuje widok tabeli punkt w czasie przy użyciu metod zbiorczych - zmiany przyrostowe nie są śledzone ani stosowane. Replikacja transakcyjna działa poprzez odczytywanie rekordów dziennika i generowanie odpowiednich transakcji w celu zastosowania zmian u subskrybentów. Scalanie replikacji śledzi zmiany za pomocą wyzwalaczy i tabel metadanych.

Literatura pokrewna: Optymalizacja zapytań T-SQL, które zmieniają dane

Paul White mówi GoFundMonica
źródło