T-SQL ISNULL()优化

时间:2009-09-18 14:09:29

标签: sql sql-server tsql optimization

我在继承的存储过程中加入了这个子句:

WHERE a.is_active = 1
AND b.due_date <= ISNULL(@due_date_limit, b.due_date)

如何重新编写此文件以删除ISNULL,因为它会导致严重的性能问题?

7 个答案:

答案 0 :(得分:7)

在这个例子中,我会有一个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

答案 1 :(得分:3)

此类查询导致性能不佳的最常见原因是优化程序无法确定@due_date_limit的大多数查询的典型值。通常,后续执行生成和重新使用的计划有利于值为空的情况。

从SQL 2005开始,您可以使用“OPTIMIZE FOR”选项指导优化器: -

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'))

答案 2 :(得分:2)

AND @due_date_limit IS NULL OR b.due_date <= @due_date_limit

但我不太确定它会快得多。

答案 3 :(得分:2)

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为空时),或使用&lt; =进行过滤可能会返回大量记录,这将消除使用索引的任何机会,并且需要完整的表扫描。这可能正是您所经历的。

答案 4 :(得分:1)

@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>

答案 5 :(得分:1)

COALESCE(@due_date_limit, b.due_date)

可能有帮助

答案 6 :(得分:0)

由于@due_date_limit是一个存储过程变量,您可以在查询之前检查NULL,并在需要时将其设置为默认值,从而消除{{1}中的ISNULL检查}。clause。

WHERE

然后你的IF (@due_date_limit IS NULL) BEGIN SET @due_date_limit = '09/01/2009'; END 子句看起来就像这样:

WHERE