我有一本條款加入在存儲過程中我繼承:T-SQL ISNULL()優化
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
如何將我重新寫這個刪除ISNULL因爲它導致嚴重的性能問題?
我有一本條款加入在存儲過程中我繼承:T-SQL ISNULL()優化
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
如何將我重新寫這個刪除ISNULL因爲它導致嚴重的性能問題?
,我將有一個if語句,檢查@due_date_limit
IF (@due_date_limit IS NULL)
BEGIN
...
WHERE a.is_active = 1 --not required to compare b.due_date <= b.due_date
END
ELSE
BEGIN
...
WHERE a.is_active = 1
AND b.due_date <= @due_date_limit
END
AND @due_date_limit IS NULL OR b.due_date <= @due_date_limit
,但我不敢肯定這將是快得多。
在這種情況下如果存在索引。 – recursive 2009-09-18 14:19:24
指數不是一個問題 - 即使存在,該指數也只會在下半年使用。這遠比ISNULL/COALESCE建議好。 – 2009-09-18 14:39:31
@due_date_limit是一個存儲過程變量,因此可以在此查詢中提取出來一起:
if (@due_date_limit is NULL)
<run query that works when @due_date_limit is NULL>
else
<run query that works when @due_date_limit is NOT NULL>
COALESCE(@due_date_limit, b.due_date)
可能會幫助
這會優雅地處理事情,但執行1 = 1的等價物是一種浪費。 – 2009-09-18 14:33:44
是否有due_Date上的索引?如果不添加一個,然後檢查性能。如果已經存在,則更改爲兩個單獨的語句
If @due_date_limit is null
Select [stuff]
From Table
Else
Select [stuff]
From Table
Where b.due_date <= @due_date_limit
但意識到不能過濾(當@due_date_limit爲空),或使用<過濾=有可能返回的記錄相當數量,這將消除任何機會使用索引並需要完整的表掃描。這可能是你正在經歷的。
這種類型的查詢性能低下的最常見原因是,優化程序無法確定@due_date_limit對大多數查詢的典型值。通常,由後續執行生成並重新使用的計劃有利於值爲空的情況。
由於SQL 2005,你可以使用指導優化器的「優化」選項: -
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
OPTION (OPTIMIZE FOR (@due_date_limit = '09/01/2009'))
如果該參數爲空,爲什麼仍要比較值?你不這樣做,所以不要使用ISNULL/COALESCE作爲可選參數。 – 2009-09-18 14:40:57
由於@due_date_limit
是一個存儲過程的變量,你可以檢查它的NULL
查詢之前,並將其設置到需要的默認值,從而消除WHERE
條款中的ISNULL檢查。
IF (@due_date_limit IS NULL)
BEGIN
SET @due_date_limit = '09/01/2009';
END
,然後你WHERE
條款只會是這樣的:
WHERE a.is_active = 1
AND b.due_date <= @due_date_limit
如果你需要它與列記錄相同以滿足'<='操作符條件,那麼astander的答案是一個更好的解決方案,否則設置如果在這樣的查詢之前,因爲它會更快並且沒有檢查。 – johntrepreneur 2013-07-08 01:29:16
SQL Server版本? – AnthonyWJones 2009-09-18 14:11:51