Ein erster Blick auf die Ausführungspläne zeigt, dass der Ausdruck 1/0
in den Compute Scalar-Operatoren definiert ist:
Obwohl Ausführungspläne ganz links ausgeführt werden und iterativ untergeordnete Iteratoren aufgerufen werden Open
und GetRow
Methoden zum Zurückgeben von Ergebnissen verwendet werden, enthält SQL Server 2005 und höher eine Optimierung, bei der Ausdrücke häufig nur von einem Compute Scalar definiert werden und die Auswertung bis zu einem späteren Zeitpunkt verschoben wird Operation erfordert das Ergebnis :
In diesem Fall wird der Ausdruck Ergebnis wird nur dann benötigt , wenn die Zeile für die Rückkehr an den Client Montag (die Sie von auftretenden am grünen denken SELECT
Symbol). Nach dieser Logik würde eine verzögerte Auswertung bedeuten, dass der Ausdruck niemals ausgewertet wird, da keiner der beiden Pläne eine Rückgabezeile generiert. Um den Punkt ein wenig zu bearbeiten, geben weder der Clustered Index Seek noch der Table Scan eine Zeile zurück, sodass für die Rückgabe an den Client keine Zeile zusammengestellt werden muss.
Es gibt jedoch eine separate Optimierung, bei der einige Ausdrücke als Laufzeitkonstanten identifiziert und so einmalig ausgewertet werden können, bevor die Abfrageausführung beginnt . In diesem Fall kann ein Hinweis darauf im showplan XML gefunden werden (Clustered-Index-Suchplan links, Table-Scan-Plan rechts):
In diesem Blogbeitrag habe ich mehr über die zugrunde liegenden Mechanismen und deren Auswirkungen auf die Leistung geschrieben . Anhand der dort bereitgestellten Informationen können wir die erste Abfrage so ändern, dass beide Ausdrücke ausgewertet und zwischengespeichert werden, bevor die Ausführung beginnt:
select 1/0 * CONVERT(integer, @@DBTS)
from #temp
where id = 1
select 1/0
from #temp2
where id = 1
Der erste Plan enthält jetzt auch einen konstanten Ausdrucksverweis, und beide Abfragen erzeugen die Fehlermeldung. Das XML für die erste Abfrage enthält:
Weitere Informationen: Skalare, Ausdrücke und Leistung berechnen