Wstępne spojrzenie na plany wykonania pokazuje, że wyrażenie 1/0
jest zdefiniowane w operatorach Compal Scalar:
Teraz, mimo że plany wykonania zaczynają się wykonywać po lewej stronie, iteracyjnie wywoływanie Open
i GetRow
metody iteratorów potomnych w celu zwrócenia wyników, SQL Server 2005 i nowsze wersje zawierają optymalizację, w której wyrażenia są często definiowane tylko przez skalar obliczeniowy, a ocena jest odraczana do następnego operacja wymaga wyniku :
W takim przypadku wynik wyrażenia jest potrzebny tylko podczas zestawiania wiersza w celu zwrotu klientowi (co można pomyśleć o występowaniu przy zielonej SELECT
ikonie). Zgodnie z tą logiką odroczona ocena oznaczałaby, że wyrażenie nigdy nie jest oceniane, ponieważ żaden plan nie generuje wiersza zwracanego. Aby trochę się skupić na tym punkcie, ani wyszukiwanie klastrowe indeksu, ani skanowanie tabeli nie zwracają wiersza, więc nie ma żadnego wiersza do zebrania w celu zwrotu klientowi.
Istnieje jednak osobna optymalizacja, w której niektóre wyrażenia mogą zostać zidentyfikowane jako stałe środowiska wykonawczego, a więc ocenione raz przed rozpoczęciem wykonywania zapytania . W takim przypadku wskazanie, że tak się stało, można znaleźć w pliku XML showplan (Plan wyszukiwania indeksów klastrowych po lewej, Plan skanowania tabeli po prawej):
W tym wpisie na blogu napisałem więcej o mechanizmach leżących u ich podstaw i o tym, jak mogą one wpłynąć na wydajność . Korzystając z informacji tam zawartych, możemy zmodyfikować pierwsze zapytanie, aby oba wyrażenia były oceniane i buforowane przed rozpoczęciem wykonywania:
select 1/0 * CONVERT(integer, @@DBTS)
from #temp
where id = 1
select 1/0
from #temp2
where id = 1
Teraz pierwszy plan zawiera również stałe odwołanie do wyrażenia, a oba zapytania powodują wyświetlenie komunikatu o błędzie. Kod XML pierwszego zapytania zawiera:
Więcej informacji: Oblicz skalary, wyrażenia i wydajność