如何使这句话更快:“startDate和NULL之间的paramDate”?

时间:2009-05-11 11:48:49

标签: sql sql-server tsql between

当endDate为null时,这个查询花了很长时间(我认为它是关于case语句,在case语句之前很快)

SELECT * 
FROM HastaKurumlari
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END) 

当endDate为null以使其更快时,我应该使用什么?

4 个答案:

答案 0 :(得分:1)

您可以尝试coalesce功能:

select * 
from HastaKurumlari
where convert(smalldatetime, '21-05-2009', 103) 
    between startDate and coalesce(endDate, getdate());

唯一可以确定的方法是尝试任何替代方案并查看为每个查询生成的执行计划。

答案 1 :(得分:1)

如果它对性能至关重要,那么可能只是不使用null作为开放结束日期 - 请使用支持的最大日期时间(可能是9个)。

我也会单独进行转换:

DECLARE @when datetime
SET @when = CONVERT(SMALLDATETIME,'21-05-2009',103) 

SELECT * 
  FROM HastaKurumlari
WHERE @when
BETWEEN startDate AND endDate

上面和你原来的东西还有点不同;如果你能解释一下GETDATE()检查的意图,我可能会整理一下(阅读:修复)。

答案 2 :(得分:1)

这是没有CONVERT或CASE的查询:

SELECT * 
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,getdate())

为了确保Sql Server不会为每一行评估getdate(),你可以缓存它,虽然我很确定默认情况下Sql Server足够聪明:

declare @now datetime
set @now = getdate()

SELECT * 
FROM HastaKurumlari
WHERE '21-05-2009' between startDate and IsNull(endDate,@now)

发布查询计划有助于解释查询缓慢的原因:

SET SHOWPLAN_TEXT ON
go
SELECT * 
FROM HastaKurumlari
WHERE CONVERT(SMALLDATETIME,'21-05-2009',103) 
BETWEEN startDate 
    AND (CASE WHEN endDate IS NULL THEN GETDATE() ELSE endDate END)

答案 3 :(得分:1)

作为一个起点,将GETDATE()分解出来,使其只调用一次,你应该看到速度有所提高。

你编写它的方式是每次enddate为null时要求评估GETDATE()。

由于GETDATE()是一个non-deterministic函数,因此无法优化查询,并且该查询将无法执行。