SQL Server IS NULL in WHERE clause causing query to run slow

oprakyz7  于 2023-08-02  发布在  其他
关注(0)|答案(4)|浏览(154)

I have a query that runs quickly without the is null parameter in the Where clause, but when I add it back in it takes more than 10 minutes to run.

SELECT
    Parent_FRID, Name, lvl2desc, capyr, crpprjamt, empprjamt,
    othprjamt AS Other_Projected, Fcrprepamt, Femprepamt, Fothrepamt, NFcrprepamt,
    NFemprepamt, NFothrepamt, crpamt, empamt, othamt, Audited, Previous_Corp_Amt,
    Previous_Emp_Amt, Previous_Total_Projected, Previous_Total_Reported,
    Previous_Audited, crpfnl, empfnl, othfnl
FROM
    Camp_Sum_6_Current_14
WHERE
    cnttyp IS NULL AND
    lvl2 <> '1020' AND
    doncls in ('AG','CO')

I have tried everything and I can't get it figured out. I tried a subquery. I tried changing the Null values to 'None' in the original table. The same query runs fine with is not null.

vyu0f0g1

vyu0f0g11#

If you put an index on doncls , this will allow SQL-Server to filter the "AG" and "AC" very quickly. Then the other conditions will run on a very reduced row set. (Assuming that only a small percentage of the rows have "AG" or "AC".)

An index on lvl2 will not help much, because the condition on this column is formulated as an exclusion.

Depending on how many NULLs are in cnttyp an index can help there too.

Indexes only help, if the conditions using them are very selective. I.e. if and index helps to exclude 95% of the rows, it is useful. If it excludes only 50% of the rows, a table scan or index scan will probably be faster.

xeufq47z

xeufq47z2#

try use cte

with xyz as (SELECT
    Parent_FRID, Name, lvl2desc, capyr, crpprjamt, empprjamt,
    othprjamt AS Other_Projected, Fcrprepamt, Femprepamt, Fothrepamt, NFcrprepamt,
    NFemprepamt, NFothrepamt, crpamt, empamt, othamt, Audited, Previous_Corp_Amt,
    Previous_Emp_Amt, Previous_Total_Projected, Previous_Total_Reported,
    Previous_Audited, crpfnl, empfnl, othfnl FROM
    Camp_Sum_6_Current_14)

select *  from xyz WHERE
    cnttyp IS NULL AND
    lvl2 <> '1020' AND
    doncls in ('AG','CO')
rsaldnfx

rsaldnfx3#

try subquery

select   
 
    Parent_FRID, Name, lvl2desc, capyr, crpprjamt, empprjamt,
    othprjamt AS Other_Projected, Fcrprepamt, Femprepamt, Fothrepamt, NFcrprepamt,
    NFemprepamt, NFothrepamt, crpamt, empamt, othamt, Audited, Previous_Corp_Amt,
    Previous_Emp_Amt, Previous_Total_Projected, Previous_Total_Reported,
    Previous_Audited, crpfnl, empfnl, othfnl
from 

    Camp_Sum_6_Current_14

WHERE

    lvl2 <> '1020' AND
    doncls in ('AG','CO') AND
    Parent_FRID in

(SELECT
    Parent_FRID
FROM
    Camp_Sum_6_Current_14
WHERE
    cnttyp IS NULL )
ebdffaop

ebdffaop4#

WITH DATA AS 
(
SELECT
    Parent_FRID, Name, lvl2desc, capyr, crpprjamt, empprjamt,
    othprjamt AS Other_Projected, Fcrprepamt, Femprepamt, Fothrepamt, NFcrprepamt,
    NFemprepamt, NFothrepamt, crpamt, empamt, othamt, Audited, Previous_Corp_Amt,
    Previous_Emp_Amt, Previous_Total_Projected, Previous_Total_Reported,
    Previous_Audited, crpfnl, empfnl, othfnl, ISNULL(cnttyp,0) AS NULLCHECK
FROM
    Camp_Sum_6_Current_14
WHERE
        lvl2 <> '1020' AND
    doncls in ('AG','CO')
)
SELECT * FROM DATA
WHERE NULLCHECK = 0

相关问题