2011-05-12 23 views
2

我在玩两个非常简单的查询。有一个非聚集索引StartDateEndDate以及Id作为包含列。可选参数和日期索引

DECLARE @startDate DATETIME, @endDate DATETIME 
SELECT @startDate = '4/1/2011', @endDate = '5/1/2011' 

-- Does Index Scan (slow) 
SELECT Id 
FROM dbo.Table 
WHERE 
    (@startDate IS NULL OR StartDate >= @startDate) AND 
    (@endDate IS NULL OR EndDate < @endDate) 

-- Does Index Seek (fast) 
SELECT Id 
FROM dbo.Table 
WHERE 
    (StartDate >= @startDate) AND 
    (EndDate < @endDate) 

有什么办法重新安排,预先计算,或以其他方式更改查询有一个索引查找发生在第一个例子吗?

编辑:我知道这是一个非常基本的索引问题,但我还没有找到一个好的解决方案。请注意,我正在声明这些变量,但这些将是sproc中的参数。

回答

2

以下情况如何?

DECLARE @startDate DATETIME, @endDate DATETIME 
SELECT @startDate = '4/1/2011', @endDate = '5/1/2011' 

SELECT Id 
FROM dbo.Table 
WHERE 
    StartDate >= ISNULL(@startDate, '1/1/1753') 
    AND 
    EndDate < ISNULL(@endDate, '12/31/9999') 

此代码可能是坏,如果你有12/31/9999在表的结束日期,你实际上想从你的结果集返回,但往往是如何发生的呢?

+0

这完全不一样 - 任何带有NULL EndDate或StartDate的东西都会被排除,而OP的第一个查询则不是这样。 – MartW 2011-05-12 18:13:37

+0

@CodeByMoonlight:对,在我的情况下,StartDate不能有空值,但是EndDate可以,所以这会中断。 – 2011-05-12 18:15:26

+0

@CodeByMoonlight:实际上,它不能使用'EndDate'作为seek谓词,但它可以使用'StartDate',它仍然有点帮助。通常只有最近的条目才会被取消,所以这已经是一个巨大的帮助。为了原始问题的目的,而不是我的具体实现,如果'StartDate'可以为空,甚至可以这样做吗? – 2011-05-12 18:18:15