Czy istnieje jakikolwiek sposób, aby wynik wymyślił dokładnie 3 różne przewodniki i nic więcej? Mam nadzieję, że będę w stanie lepiej odpowiadać na pytania w przyszłości, włączając przewodniki po planach z zapytaniami typu CTE, do których wielokrotnie się odwołujemy, aby przezwyciężyć niektóre dziwactwa SQL Server CTE.
Nie dzisiaj. Nierekurencyjne wspólne wyrażenia tabelowe (CTE) są traktowane jako wbudowane definicje widoku i są rozszerzane do logicznego drzewa zapytań w każdym miejscu, do którego się odwołują (podobnie jak zwykłe definicje widoku) przed optymalizacją. Drzewo logiczne dla twojego zapytania to:
LogOp_OrderByCOL: Union1007 ASC COL: Union1015 ASC
LogOp_Project COL: Union1006 COL: Union1007 COL: Union1014 COL: Union1015
LogOp_Join
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_ViewAnchor
LogOp_UnionAll
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
LogOp_Project ScaOp_Intrinsic newid, ScaOp_Const
Zwróć uwagę na dwie kotwice widoku i sześć wywołań funkcji wewnętrznej newid
przed rozpoczęciem optymalizacji. Niemniej jednak wiele osób uważa, że optymalizator powinien być w stanie stwierdzić, że rozwinięte poddrzewa były pierwotnie pojedynczym obiektem odniesienia i odpowiednio uprościć. Pojawiło się również kilka żądań Connect, aby umożliwić jawne zmaterializowanie CTE lub tabeli pochodnej.
Bardziej ogólna implementacja spowodowałaby, że optymalizator rozważyłby zmaterializowanie dowolnych wspólnych wyrażeń w celu poprawy wydajności ( CASE
z podzapytaniem to kolejny przykład, w którym mogą wystąpić problemy dzisiaj). Microsoft Research opublikował artykuł (PDF) na ten temat w 2007 roku, choć do tej pory nie został zaimplementowany. Na razie ograniczamy się do jawnej materializacji przy użyciu takich zmiennych, jak tabele tymczasowe.
SQLKiwi wspomniał o opracowywaniu planów w SSIS, czy istnieje sposób lub przydatne narzędzie pomagające w opracowaniu dobrego planu dla SQL Server?
To było po prostu pobożne życzenie i znacznie wykroczyło poza pomysł modyfikacji przewodników po planach. Zasadniczo możliwe jest napisanie narzędzia do bezpośredniej manipulacji programem XML planu, ale bez konkretnej oprzyrządowania optymalizatora użycie tego narzędzia byłoby prawdopodobnie frustrujące dla użytkownika (i programista pomyślałby o tym).
W szczególnym kontekście tego pytania takie narzędzie nadal nie byłoby w stanie zmaterializować zawartości CTE w sposób, który mógłby być wykorzystany przez wielu konsumentów (w tym przypadku zasilenie obu danych wejściowych łączeniem krzyżowym). Optymalizator i silnik wykonawczy obsługują szpule wielu konsumentów, ale tylko do określonych celów - żadnego z nich nie można zastosować w tym konkretnym przykładzie.
Chociaż nie jestem pewien, mam dość silne przeczucie, że RelOps można śledzić (zagnieżdżona pętla, Lazy Spool), nawet jeśli zapytanie nie jest dokładnie takie samo jak plan - na przykład, jeśli dodałeś 4 i 5 do CTE , nadal korzysta z tego samego planu (pozornie przetestowanego na SQL Server 2012 RTM Express).
Istnieje tutaj rozsądna elastyczność. Szeroki kształt planu XML służy do kierowania poszukiwanie ostatecznego planu (choć wiele atrybutów są całkowicie ignorowane np typ partycji na giełdach) i normalne zasady wyszukiwania są znacznie złagodzone, jak również. Na przykład wcześniejsze przycinanie alternatyw opartych na kosztach jest wyłączone, dozwolone jest jawne wprowadzenie połączeń krzyżowych, a operacje skalarne są ignorowane.
Jest zbyt wiele szczegółów, aby je zagłębić, ale nie można wymusić umieszczenia filtrów i skalarów obliczeniowych, a predykaty formularza column = value
są uogólnione, więc plan zawierający X = 1
lub X = @X
może być zastosowany do zapytania zawierającego X = 502
lub X = @Y
. Ta szczególna elastyczność może znacznie pomóc w znalezieniu naturalnego planu wymuszenia.
W konkretnym przykładzie stałą Union All zawsze można zaimplementować jako skanowanie ciągłe; liczba danych wejściowych do Unii Wszystkie nie ma znaczenia.