Sql WHERE子句中为NULL,导致查询运行缓慢

Sql WHERE子句中为NULL,导致查询运行缓慢,sql,sql-server,Sql,Sql Server,我有一个查询,在Where子句中没有is null参数的情况下可以快速运行,但是当我将其添加回Where子句中时,它需要10分钟以上的时间才能运行 SELECT Parent_FRID, Name, lvl2desc, capyr, crpprjamt, empprjamt, othprjamt AS Other_Projected, Fcrprepamt, Femprepamt, Fothrepamt, NFcrprepamt, NFemprepamt, NFothre

我有一个查询,在Where子句中没有is null参数的情况下可以快速运行,但是当我将其添加回Where子句中时,它需要10分钟以上的时间才能运行

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')
我什么都试过了,但我想不出来。我尝试了一个子查询。我尝试将原始表中的空值更改为“无”。同一查询在不为null的情况下运行良好

如果在doncls上放置索引,这将允许SQL Server快速过滤AG和AC。然后,其他条件将在非常精简的行集合上运行。假设只有一小部分行具有AG或AC

lvl2上的索引不会有多大帮助,因为此列上的条件被表示为排除

根据cnttyp中有多少空值,索引也会有所帮助

索引只有在使用它们的条件非常有选择性的情况下才有帮助。也就是说,如果and index有助于排除95%的行,那么它是有用的。如果只排除50%的行,则表扫描或索引扫描可能会更快。

尝试子查询

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 )
尝试使用cte


问题不是因为您使用的是NULL还是not,而是因为添加了一个新的过滤器,可能会强制对您的表执行扫描。cnttyp列上有索引吗?搜索短语sargable。表中有多少条记录?请发布一个执行计划。ID通常指主键,所以我假设它确实是唯一的。毫无疑问,它在某些表格中是独一无二的。我看不出为什么那张桌子会被称为Camp_Sum_6_Current_14。这个请求已经有六年了。在写答案时,请写一个答案,不要只写一些代码。您认为原始查询有什么问题?您的查询如何解决此问题?为什么你认为这会更好?
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')
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