Proste USUŃ, ale skomplikowany plan wykonania

9

Po uruchomieniu tego usuwania:

DELETE FROM ETLHeaders WHERE ETLHeaderID < 32465870

... usuwa 39 157 wierszy. Powinno być proste, ponieważ usuwa się na ETLHeaderID, który jest indeksem klastrowym i kluczem podstawowym. Ale (zgodnie z planem wykonania) wydaje się, że uderza w 361 190 wierszy i używa innych indeksów. Tabela ma pole z typem danych XML (w przypadku, gdy wpływa to na DELETE).

Wszelkie pomysły, dlaczego i jak mogę przyspieszyć usuwanie?

Plan wykonania tutaj: http://sharetext.org/qwDY Schemat tabeli tutaj: http://sharetext.org/Vl9j

dzięki

Craig HB
źródło

Odpowiedzi:

10

Najwyższe poziomy planu dotyczą usuwania wierszy z tabeli podstawowej (indeks klastrowany) i utrzymywania czterech indeksów nieklastrowanych. Dwa z tych indeksów są utrzymywane wiersz po wierszu w tym samym czasie, gdy przetwarzane są skasowane indeksy. Są to „+2 indeksy nieklastrowane” podświetlone na zielono poniżej.

W przypadku pozostałych dwóch indeksów nieklastrowanych optymalizator zdecydował, że najlepiej zapisać klucze tych indeksów w stole roboczym tempdb (bufor Eager), a następnie dwukrotnie odtworzyć bufor, sortując według kluczy indeksu, aby promować sekwencyjny wzór dostępu.

Regularna konserwacja indeksu

Ostatnia sekwencja operacji dotyczy utrzymywania xmlindeksów pierwotnego i wtórnego , które nie zostały uwzględnione w skrypcie DDL:

Obsługa indeksu XML

Niewiele można z tym zrobić. Indeksy i xmlindeksy nieklastrowane muszą być zsynchronizowane z danymi w tabeli podstawowej. Koszt utrzymania takich indeksów jest częścią kompromisu, jaki podejmujesz, tworząc dodatkowe indeksy na stole.

To powiedziawszy, xmlindeksy są szczególnie problematyczne. Optymalizatorowi bardzo trudno jest dokładnie oszacować, ile wierszy zostanie zakwalifikowanych w tej sytuacji. W rzeczywistości znacznie zawyżono szacunki dla xmlindeksu, co spowodowało przyznanie prawie 12 GB pamięci dla tego zapytania (choć w czasie wykonywania jest używane tylko 28 MB):

Szacowana liczba wierszy

Możesz rozważyć usunięcie w mniejszych partiach, mając nadzieję na ograniczenie wpływu nadmiaru pamięci.

Możesz także przetestować wydajność planu bez użycia metod OPTION (QUERYTRACEON 8795). Jest to nieudokumentowana flaga śledzenia, więc powinieneś wypróbować ją tylko w systemie rozwojowym lub testowym, nigdy w produkcji. Jeśli wynikowy plan jest znacznie szybszy, możesz przechwycić XML planu i użyć go do utworzenia Przewodnika po planach dla zapytania produkcyjnego.

Paul White 9
źródło
3

Jesteś na dobrej drodze - problemem jest indeks XML. Oczywiście istnieje zarówno podstawowy, jak i dodatkowy indeks XML.

Podczas wykonywania operacji DELETE względem tabeli podstawowej (ETLHeaders) dane należy również usunąć z każdego indeksu tej tabeli. Ten narzut może być znaczący, szczególnie w przypadku indeksów XML.

Indeks powodujący długi czas trwania jest wtórnym indeksem XML [XML_IX_ETLHeaders_Property]. 39 157 wierszy w „tabeli relacyjnej” odnosi się do 361 190 wierszy w głównym indeksie XML [XML_IX_ETLHeaders]. Te wiersze 361k muszą zostać posortowane, aby można było ich użyć do usunięcia indeksu dodatkowego. Ta operacja sortowania powoduje długi czas trwania zapytania. (Na marginesie, statystyki obu indeksów xml wydają się być dalekie: rzeczywisty rozmiar danych 361k wierszy podstawowego indeksu xml wynosi 160 MB, podczas gdy szacowany rozmiar danych to prawie 4 TB (tak, 4 TerraByte !!)) .

Jedyną opcją, którą widzę, aby przyspieszyć to zapytanie, jest wyeliminowanie dodatkowego indeksu XML. W zależności od danych lepszym rozwiązaniem może być niszczenie danych XML w tabeli relacyjnej.

Lmu92
źródło