2014-10-30 308 views
1

我有一個快速運行而Where Where子句中沒有is null參數的查詢,但是當我將它添加回來需要超過10分鐘才能運行。WHERE子句中的NULL導致查詢運行緩慢

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值更改爲'None'。相同的查詢運行良好,不爲空。

+3

這個問題並不是因爲你正在使用'IS NULL',而是因爲添加了一個新的過濾器,可能會迫使你在你的表上執行掃描。 cnttyp列中是否有索引? – Lamak 2014-10-30 17:42:34

+0

搜索短語「sargable」。 http://stackoverflow.com/questions/799584/what-makes-a-sql-statement-sargable – EBarr 2014-10-30 17:46:43

+0

表中有多少條記錄? – 2014-10-30 17:48:01

回答

0

如果您將索引放在doncls上,這將允許SQL-Server非常快地過濾"AG""AC"。然後其他條件將在非常小的行集上運行。 (假設只有很小比例的行具有「AG」或「AC」)。

lvl2上的索引不會有多大幫助,因爲此列上的條件被表述爲排除。

根據cnttyp中有多少個NULL,索引也可以幫助您。

索引只有幫助,如果使用它們的條件是非常有選擇性的。即如果和索引有助於排除95%的行,則很有用。如果它僅排除50%的行,則表掃描或索引掃描可能會更快。

0

嘗試子查詢

選擇

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 

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)

+0

如果'Parent_FRID'是唯一的,這將只能正常工作。 – 2014-10-30 18:45:11

+0

「ID」通常指的是主鍵,所以我認爲它是唯一的。 – Behnam 2014-10-30 18:50:44

+0

。 。毫無疑問,它在* some *表中是獨一無二的。我看不出爲什麼這張桌子叫做'Camp_Sum_6_Current_14'。 – 2014-10-30 21:52:54

0

嘗試使用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') 
0

您是否嘗試過WHERE子句中使用= NULL,而不是IS NULL
這幫助我,但我仍然還沒有想出的原因...
例如我的查詢是這樣的: 一些選擇計數後和內部聯接報表

WHERE l02_bnr LIKE @bnr +'' 
AND ((@Status IS NULL) OR l02_status = @Status) 

我改變了((@Status IS NULL)(@Status = NULL)和它去從20多歲到5秒的表現。