我继承了一个存储过程,在其中有一个关联查询的语句:
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
如何重写此代码以删除ISNULL函数,因为它导致严重的性能问题?
我继承了一个存储过程,在其中有一个关联查询的语句:
WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)
如何重写此代码以删除ISNULL函数,因为它导致严重的性能问题?
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
但我不确定它会更快。
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'))
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是一个存储过程变量,因此可以从这个查询中完全分离出来:
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)
可能有帮助
由于 @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