2014-12-14 20 views
9

Sto lavorando per ottimizzare alcune stored procedure molto utilizzate e ho attraversato uno scenario che ha sollevato una domanda per la quale non sono riuscito a trovare alcuna risposta: quando si valuta TSQL in una stored procedure, SQL Server esegue il cortocircuito sull'istruzione IF?Le istruzioni IF di cortocircuito di SQL Server?

Per esempio, assumere una stored procedure ha un codice simile a:

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

In questo scenario fa di SQL Server cortocircuito la valutazione in modo tale che la dichiarazione EXISTS non viene mai eseguito quando la clausola precedente restituisce true?

Se mai o solo qualche volta lo fa, allora abbiamo qualche riscrittura davanti a noi.

+2

Non garantito. Controlla il piano di esecuzione per vedere se lo fa nel tuo caso. –

+0

Grazie, "non garantito" è quello che stavo cercando. Il problema è che queste stored procedure sono eseguite su centinaia di DB cliente, quindi se il piano di esecuzione lo determina, non possiamo presumere che verrà valutato lo stesso sul sistema di ogni cliente e che è necessario riscrivere. –

+1

Se si desidera una garanzia di ghisa, la separazione in più istruzioni 'if' lo farà. Quando [ho visto questo prima] (http://stackoverflow.com/a/5543985/73226) ho trovato alcuni esempi di questo non cortocircuito. Si potrebbe anche esaminare l'uso di dichiarazioni di casi. –

risposta

4

Anche se sembra funzionare, non dovrebbe essere invocato. La dichiarazione CASE è l'unica cosa che la documentazione indica come cortocircuito, ma anche quello non è (o almeno non lo era) sempre il caso (ih ih). Ecco uno bug che è stato risolto per fortuna a partire da SQL Server 2012 (vedere i commenti).

Oltre alla tana del coniglio (interessante, di sicuro) di link nei commenti del commento postato da @ Martin sulla questione, si dovrebbe anche controllare questo articolo:

Understanding T-SQL Expression Short-Circuiting

e il forum di discussione relativo a quell'articolo.

3

La buona notizia è che sembra in cortocircuito. Ecco un esempio minimo:

DECLARE @condition1 bit = 1 

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

Quando @condition è impostato su 1, questo è il piano di esecuzione: 0 righe scansionati da sys.objects

execution plan 1

quando @condition è impostato a 0, scansionato il sys.objects tabella:

execution plan 2

Ma non c'è alcuna garanzia che questo sarà il caso ogni volta.