sqlsql-servert-sqlquery-optimization

SQL Server select query where clause


Evaluating one side of OR in my query. I have a SQL Server query with 2 separate complex filters. The intention to combine them in one as follows:

Declare @BoolSet Bit = 0

Select Distinct Top (1200)
    a.called, a.engineer, a.response, a.call_no
From 
    [tablea] a
Inner Join 
    [tableb] b On a.id = b.id
Where 
    (@BoolSet = 1 And FirstFilter) Or (@BoolSet = 0 And SecondFilter)

FirstFilter and SecondFilter are a complex filters based purely on declared variables and columns value. I was hoping @BoolSet will essentially force SQL Server to only one side of where clause.

Run separately the queries take 2 or 3 seconds. But combined as above, the query takes minutes to run. Why? It appears SQL Server is evaluating both FirstFilter and SecondFilter completely disregarding @BoolSet. I expect it to be smarter than that. What am I missing?


Solution

  • The short answer is that your parameterized query is compiled into a single plan, which must singularly work for both variations. And one size does not fit all (it is "optimised" at compile time, not run time).

    The long answer is here :

    If you MUST have a single query, that link has a great many options. My gut feel is that UNION might be a work around...

        Select Distinct Top (1200)
            a.called, a.engineer, a.response, a.call_no
        From
            [tablea] a
        Inner Join 
            [tableb] b On a.id = b.id
        Where 
            @BoolSet = 1 AND FirstFilter
    
    UNION ALL
    
        Select Distinct Top (1200)
            a.called, a.engineer, a.response, a.call_no
        From
            [tablea] a
        Inner Join 
            [tableb] b On a.id = b.id
        Where 
            @BoolSet = 0 AND SecondFilter