Is the SQL WHERE clause short-circuit evaluated?

前端 未结 14 2462
时光取名叫无心
时光取名叫无心 2020-11-22 04:31

Are boolean expressions in SQL WHERE clauses short-circuit evaluated ?

For example:

SELECT * 
FROM Table t 
WHERE @key IS NULL OR (@key IS NOT NULL          


        
相关标签:
14条回答
  • 2020-11-22 04:38

    I typically use this for optional parameters. Is this the same as short circuiting?

    SELECT  [blah]
    FROM    Emp
    WHERE  ((@EmpID = -1) OR (@EmpID = EmpID))
    

    This gives me the option to pass in -1 or whatever to account for optional checking of an attribute. Sometimes this involves joining on multiple tables, or preferably a view.

    Very handy, not entirely sure of the extra work that it gives to the db engine.

    0 讨论(0)
  • 2020-11-22 04:40

    Here is a demo to prove that MySQL does perform WHERE clause short-circuiting:

    http://rextester.com/GVE4880

    This runs the following queries:

    SELECT myint FROM mytable WHERE myint >= 3 OR myslowfunction('query #1', myint) = 1;
    SELECT myint FROM mytable WHERE myslowfunction('query #2', myint) = 1 OR myint >= 3;
    

    The only difference between these is the order of operands in the OR condition.

    myslowfunction deliberately sleeps for a second and has the side effect of adding an entry to a log table each time it is run. Here are the results of what is logged when running the above two queries:

    myslowfunction called for query #1 with value 1
    myslowfunction called for query #1 with value 2
    myslowfunction called for query #2 with value 1
    myslowfunction called for query #2 with value 2
    myslowfunction called for query #2 with value 3
    myslowfunction called for query #2 with value 4
    

    The above shows that a slow function is executed more times when it appears on the left side of an OR condition when the other operand isn't always true (due to short-circuiting).

    0 讨论(0)
  • 2020-11-22 04:41

    I don't believe that short circuiting in SQL Server (2005) is guaranteed. SQL Server runs your query through its optimization algorithm that takes into account a lot of things (indexes, statistics, table size, resources, etc) to come up with an effective execution plan. After this evaluation, you can't say for sure that your short circuit logic is guaranteed.

    I ran into the same question myself sometime ago and my research really did not give me a definitive answer. You may write a small query to give you a sense of proof that it works but can you be sure that as the load on your database increases, the tables grow to be bigger, and things get optimized and changed in the database, that conclusion will hold. I could not and therefore erred on the side of caution and used CASE in WHERE clause to ensure short circuit.

    0 讨论(0)
  • 2020-11-22 04:43

    ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

    6.3.3.3 Rule evaluation order

    [...]

    Where the precedence is not determined by the Formats or by parentheses, effective evaluation of expressions is generally performed from left to right. However, it is implementation-dependent whether expressions are actually evaluated left to right, particularly when operands or operators might cause conditions to be raised or if the results of the expressions can be determined without completely evaluating all parts of the expression.

    0 讨论(0)
  • 2020-11-22 04:43

    For SQL Server, I think it depends on the version but my experience with SQL Server 2000 is that it still evaluates @key = t.Key even when @key is null. In other words, it does not do efficient short circuiting when evaluating the WHERE clause.

    I've seen people recommending a structure like your example as a way of doing a flexible query where the user can enter or not enter various criteria. My observation is that Key is still involved in the query plan when @key is null and if Key is indexed then it does not use the index efficiently.

    This sort of flexible query with varying criteria is probably one case where dynamically created SQL is really the best way to go. If @key is null then you simply don't include it in the query at all.

    0 讨论(0)
  • 2020-11-22 04:47

    You have to keep in mind how databases work. Given a parameterized query the db builds an execution plan based on that query without the values for the parameters. This query is used every time the query is run regardless of what the actual supplied values are. Whether the query short-circuits with certain values will not matter to the execution plan.

    0 讨论(0)
提交回复
热议问题