2014-12-14 8 views
9

Ich arbeite an der Optimierung einiger häufig verwendeter gespeicherter Prozeduren und lief über ein Szenario, das eine Frage aufwarf, für die ich keine Antworten finden konnte: Wenn TSQL in einer gespeicherten Prozedur ausgewertet wird, schließt SQL Server die IF Anweisung kurz?Verletzt SQL Server IF-Anweisungen?

zum Beispiel angenommen, ein Code der gespeicherten Prozedur hat ähnlich wie:

IF @condition1 = 1 
OR EXISTS(SELECT 1 FROM table1 WHERE column1 = @value1) 
... 

In diesem Szenario funktioniert SQL Server Kurzschluss der Auswertung, so dass die EXISTS Anweisung nie ausgeführt wird, wenn die vorhergehende Klausel true ergibt?

Wenn es nie oder nur manchmal tut, dann haben wir etwas Umschreiben vor uns.

+2

Nicht garantiert. Überprüfen Sie den Ausführungsplan, um festzustellen, ob dies in Ihrem Fall der Fall ist. –

+0

Danke, 'nicht garantiert' ist, was ich gesucht habe. Das Problem besteht darin, dass diese gespeicherten Prozeduren auf Hunderten von Kunden-DBs ausgeführt werden. Wenn der Ausführungsplan dies feststellt, können wir nicht davon ausgehen, dass sie auf jedem Kundensystem gleich ausgewertet werden und neu geschrieben werden müssen. –

+1

Wenn Sie eine Garantie auf Gusseisen haben möchten, dann wird das Aussortieren in mehrere "if" -Anweisungen das tun. Als ich das vorher sah (http://stackoverflow.com/a/5543985/73226) fand ich einige Beispiele dafür, die nicht kurzschließen. Sie könnten auch nach Fallanweisungen suchen. –

Antwort

4

Auch wenn es zu funktionieren scheint, sollte man sich nicht darauf verlassen. Die CASE Erklärung ist das einzige, was die Dokumentation als Kurzschluss angibt, aber selbst das ist nicht (oder zumindest nicht) immer der Fall (hee hee). Hier ist eine bug, die zum Glück seit SQL Server 2012 behoben wurde (siehe die Kommentare).

Neben dem Kaninchenbau (interessant, sicher) von Links in den Kommentaren aus dem Kommentar gepostet von @ Martin auf die Frage, sollten Sie auch diesen Artikel finden Sie unter:

Understanding T-SQL Expression Short-Circuiting

und das Diskussionsforum zu diesem Artikel.

3

Die gute Nachricht ist, dass es scheint kurzzuschließen. Hier ist ein minimales Beispiel:

DECLARE @condition1 bit = 1 

IF (@condition1 = 1) OR EXISTS(SELECT 1 FROM sys.objects) 
    PRINT 'True' 
ELSE 
    PRINT 'False' 

Wenn @condition auf 1 gesetzt ist, ist dies der Ausführungsplan: 0 Zeilen gescannt von sys.objects

execution plan 1

wenn @condition auf 0 gesetzt ist, scannte es die sys.objects Tabelle:

execution plan 2

Aber es gibt keine Garantie, dass dies jedes Mal der Fall sein wird.