Mam takie same obliczenia w klauzulach SELECT i GROUP BY. Czy serwer SQL faktycznie wykonuje te obliczenia dwukrotnie, czy jest wystarczająco inteligentny, aby wykonać to tylko raz?
Prosta odpowiedź jest taka, że SQL Server nie daje ogólnych gwarancji, kiedy i ile razy wyrażenie skalarne będzie oceniane w czasie wykonywania.
W optymalizatorze i silniku wykonawczym występują różnego rodzaju skomplikowane (i nieudokumentowane) zachowania dotyczące umieszczania, wykonywania i buforowania wyrażeń skalarnych. Books Online nie ma wiele do powiedzenia na ten temat, ale mówi :
Opisuje to jedno z zachowań, o których wspominałem wcześniej, odraczania wykonywania wyrażeń. O niektórych innych bieżących zachowaniach (które mogą się zmienić w dowolnym momencie) napisałem w tym poście na blogu .
Inną kwestią jest to, że model kosztów wykorzystywany przez optymalizator zapytań obecnie nie robi wiele w zakresie szacowania kosztów dla wyrażeń skalarnych. Bez solidnych ram kalkulacji kosztów bieżące wyniki opierają się na szerokiej heurystyce lub czystej szansie.
W przypadku bardzo prostych wyrażeń prawdopodobnie nie ma większego znaczenia, czy wyrażenie jest oceniane raz czy wiele razy w większości przypadków. To powiedziawszy, spotkałem się z dużymi zapytaniami, w których wydajność została niekorzystnie obniżona, gdy wyrażenie jest oceniane bardzo wiele razy nadmiarowo, lub ocena występuje w jednym wątku, w którym korzystna byłaby ocena w równoległej gałęzi wykonania plan.
Podsumowując, bieżące zachowanie jest niezdefiniowane i nie ma nic w planach wykonania, które pomogłyby ci dowiedzieć się, co się stało (i nie zawsze wygodne będzie dołączenie debugera do zbadania szczegółowych zachowań silnika, jak w poście na blogu).
Jeśli napotkasz przypadki, w których problemy z oceną skalarną mają znaczenie dla wydajności, podnieś problem ze wsparciem Microsoft. Jest to najlepszy sposób przekazywania opinii w celu ulepszenia przyszłych wersji produktu.
cross apply
w tym przypadku jest nieco rozciągnięte i bardzo prawdopodobne, że zaszkodzi wydajności, wprowadzając niepotrzebne samozłączenie.CROSS APPLY
Właśnie definiuje alias z kolumny w tym samym wierszu. Nie ma potrzeby dołączania. np.SELECT COUNT(*), hilo FROM master..spt_values CROSS APPLY (VALUES(high + low)) V(hilo) GROUP BY hilo
Wydajność to tylko jeden aspekt. Druga to łatwość konserwacji.
Osobiście zwykle wykonuję następujące czynności:
AKTUALIZACJA:
Jeśli nie lubisz zagnieżdżać, możesz utworzyć WIDOK dla każdej tabeli, w której musisz użyć złożonych wyrażeń.
Następnie możesz dokonać wyboru bez dodatkowego zagnieżdżania;
źródło