Jaki jest wewnętrzny algorytm jak wyjątkiem operatora działa pod kołdrą w SQL Server? Czy to wewnętrznie zajmuje hash każdego wiersza i porównuje?
David Lozinksi przeprowadził badanie, SQL: Najszybszy sposób wstawiania nowych rekordów tam, gdzie jeszcze nie istnieje . Pokazał, że instrukcja Except jest najszybsza dla dużej liczby wierszy; ściśle powiązane z naszymi wynikami poniżej.
Założenie: Sądzę, że lewe łączenie byłoby najszybsze, ponieważ porównuje tylko 1 kolumnę, z wyjątkiem najdłuższego, ponieważ musi porównać wszystkie kolumny.
Z tymi wynikami, teraz nasze myślenie jest wyjątkiem, z wyjątkiem tego, że automatycznie pobiera skrót każdego wiersza? Spojrzałem na plan wykonania z wyjątkiem, który wykorzystuje pewien skrót.
Tło: Nasz zespół porównywał dwie tabele stert. Tabela A Rzędy niewymienione w tabeli B zostały wstawione do tabeli B.
Tabele sterty (ze starszego systemu plików tekstowych) nie mają kluczy głównych / prowadnic / identyfikatorów. Niektóre tabele miały zduplikowane wiersze, więc znaleźliśmy wartość skrótu każdego wiersza, usunęliśmy duplikaty i utworzyliśmy identyfikatory klucza głównego.
1) Najpierw uruchomiliśmy instrukcję wyjątkiem, z wyłączeniem (kolumna mieszania)
select * from TableA
Except
Select * from TableB,
2) Następnie przeprowadziliśmy porównanie lewego łączenia między dwiema tabelami na HashRowId
select *
FROM dbo.TableA A
left join dbo.TableB B
on A.RowHash = B.RowHash
where B.Hash is null
zaskakująco, z wyjątkiem instrukcji Insert Insert było najszybsze.
Wyniki faktycznie są zbliżone do wyników testów Davida Lozinksi
źródło
Odpowiedzi:
Nie powiedziałbym, że istnieje specjalny wewnętrzny algorytm dla
EXCEPT
. PonieważA EXCEPT B
silnik pobiera odrębne (w razie potrzeby) krotki z A i odejmuje wiersze pasujące do B. Nie ma specjalnych operatorów planu zapytań. Odróżnianie i odejmowanie są realizowane za pomocą typowych operatorów, które można zobaczyć za pomocą sortowania lub łączenia. Obsługiwane są łączenie w pętli zagnieżdżonej, łączenie scalające i łączenie mieszające. Aby to pokazać, wrzucę 15 milionów wierszy w parę hałd:Optymalizator zazwyczaj podejmuje decyzje oparte na kosztach dotyczące sposobu sortowania i łączenia. Z dwoma hałdami otrzymuję haszowanie zgodnie z oczekiwaniami. Możesz oczywiście zobaczyć inne typy złączeń, dodając indeksy lub zmieniając dane w dowolnej tabeli. Poniżej wymuszam połączenia scalania i łączenia z podpowiedziami tylko w celach ilustracyjnych:
Nie. Jest implementowany jak każde inne połączenie. Jedną różnicą jest to, że wartości NULL są traktowane jako równe. Jest to specjalny rodzaj porównania, które można zobaczyć w planie wykonanie:
<Compare CompareOp="IS">
. Możesz jednak uzyskać ten sam plan dzięki T-SQL, który nie zawieraEXCEPT
słowa kluczowego. Na przykład poniższe ma dokładnie ten sam plan zapytań, coEXCEPT
zapytanie wykorzystujące sprzężenie mieszające:Zróżnicowanie XML planów wykonania ujawnia jedynie powierzchowne różnice wokół aliasów i tego typu rzeczy. Resztki sondy dla połączeń mieszających wykonują porównanie wierszy. Są takie same dla obu zapytań:
Jeśli nadal masz wątpliwości, uruchomiłem PerfView z najwyższą dostępną częstotliwością próbkowania, aby uzyskać stosy wywołań dla zapytania zi
EXCEPT
zapytania bez niego. Oto wyniki obok siebie:Nie ma prawdziwej różnicy. Stosy wywołań w tym haszowaniu referencyjnym są obecne z powodu dopasowań skrótu w planie. Jeśli dodam indeksy, aby uzyskać naturalne połączenie scalające, nie zobaczysz żadnych odniesień do mieszania w stosach połączeń:
Występujące haszowanie wynika z implementacji operatorów dopasowania mieszania. Nie ma w tym nic specjalnego,
EXCEPT
co prowadzi do specjalnego, wewnętrznego porównania skrótów.źródło