17

I am working on optimizing some heavily used stored procedures and ran across a scenario that raised a question that I couldn't find any answers for: when evaluating TSQL in a stored procedure, does SQL Server short-circuit the IF statement?

For example, assume a stored procedure has code similar to:

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

In this scenario does SQL Server short-circuit the evaluation such that the EXISTS statement is never executed when the preceding clause evaluates to true?

If it never or only sometimes does, then we have some rewriting ahead of us.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • 2
    Not guaranteed. Check the execution plan to see if it does in your case. – Martin Smith Dec 14 '14 at 23:17
  • Thanks, 'not guaranteed' is what I was looking for. The problem is that these stored procedures are executed on hundreds of customer DBs, so if the execution plan determines this, we cannot assume it will be evaluated the same on every customer's system and need to rewrite. – competent_tech Dec 14 '14 at 23:19
  • 1
    If you want a cast iron guarantee then separating out into multiple `if` statements will do that. When [I looked at this before](http://stackoverflow.com/a/5543985/73226) I found some examples of it not short circuiting. You could also look into using case statements. – Martin Smith Dec 14 '14 at 23:23
  • @MartinSmith: that is excellent info to have and I very much like the case statement approach. – competent_tech Dec 14 '14 at 23:33
  • This question seems to be asking if short circuiting occurs outside of a query. All answers and links I've seen are regarding the inside a query case. I would guess that in this particular case short circuiting does occur and is guaranteed but I have no idea. Is there anyone who can address the question of whether short circuiting occurs in a statement outside of a query (i.e. it's not in something like a Where clause)? – Jules May 09 '15 at 15:34

2 Answers2

10

Even if it appears to work, it should not be relied upon. The CASE statement is the only thing that the documentation states as being short-circuiting, but even that isn't (or at least wasn't) always the case (hee hee). Here is one bug that was fortunately fixed as of SQL Server 2012 (see the comments).

In addition to the rabbit hole (an interesting one, for sure) of links in comments from the comment posted by @Martin on the question, you should also check out this article:

Understanding T-SQL Expression Short-Circuiting

and the discussion forum related to that article.

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
4

The good news is that it seems to short-circuit. Here's a minimal example:

DECLARE @condition1 bit = 1

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

When @condition is set to 1, this is the execution plan: 0 rows scanned from sys.objects

execution plan 1

when @condition is set to 0, it scanned the sys.objects table:

execution plan 2

But there is no guarantee that this will be the case every time.

Code Different
  • 90,614
  • 16
  • 144
  • 163