Mam zapytanie, które łączy kilka tabel i działa dość źle - oszacowania wierszy są znacznie (1000 razy) wyłączone, a połączenie zagnieżdżonych pętli jest wybrane, co powoduje wielokrotne skanowanie tabeli. Kształt zapytania jest dość prosty, wygląda mniej więcej tak:
SELECT t1.id
FROM t1
INNER JOIN t2 ON t1.id = t2.t1_id
LEFT OUTER JOIN t3 ON t2.id = t3.t2_id
LEFT OUTER JOIN t4 ON t3.t4_id = t4.id
WHERE t4.id = some_GUID
Rozważając zapytanie, zauważyłem, że kiedy sugeruję, aby użyć sprzężenia scalania dla jednego ze sprzężeń, działa ono wiele razy szybciej. Rozumiem to - Scalanie złączenia jest lepszą opcją dla danych, które są łączone, ale SQL Server po prostu nie szacuje tego przy wyborze zagnieżdżonych pętli.
Nie do końca rozumiem, dlaczego ta wskazówka dotycząca łączenia zmienia wszystkie prognozy dla wszystkich operatorów planu? Po przeczytaniu różnych artykułów i książek założyłem, że oszacowania liczności są wykonywane przed zbudowaniem planu, więc użycie podpowiedzi nie zmieniłoby oszacowań, ale raczej wyraźnie powiedziało SQL Serverowi, aby użył konkretnej fizycznej implementacji łączenia.
Widzę jednak, że wskazówka dotycząca scalania powoduje, że wszystkie szacunki stają się prawie idealne. Dlaczego tak się dzieje i czy są jakieś popularne techniki, dzięki którym optymalizator zapytań dokonuje lepszej oceny bez podpowiedzi - biorąc pod uwagę, że statystyki oczywiście na to pozwalają?
UPD: anonimowe plany wykonania można znaleźć tutaj: https://www.dropbox.com/s/hchfuru35qqj89s/merge_join.sqlplan?dl=0 https://www.dropbox.com/s/38sjtv0t7vjjfdp/no_hints_join.sqlplan?dl = 0
Sprawdziłem statystyki używane przez oba zapytania przy użyciu TF 3604, 9292 i 9204, a te są identyczne. Jednak indeksy, które są skanowane / wyszukiwane, różnią się między zapytaniami.
Poza tym próbowałem uruchomić kwerendę z OPTION (FORCE ORDER)
- działa nawet szybciej niż przy użyciu łączenia scalającego, wybierając HASH MATCH dla każdego sprzężenia.