SQL Server日期索引滞后一天

时间:2016-09-02 19:41:06

标签: sql-server tsql indexing

我有一个列dt的表,我在WHERE子句中使用,另一列identifier用于连接。 dtidentifier都已编入索引。

对于今天之前的所有日期,以下查询在不到一秒的时间内运行:

select SRDtoday.*
from SRD as SRDtoday
left join (select * from SRD where convert(date, dt) = convert(date, dateadd(day, -1, getdate()))) as SRDyesterday ON (SRDtoday.Identifier = SRDyesterday.Identifier)
where convert(date, SRDtoday.dt) = convert(date, dateadd(day, -1, getdate()))

然而,当我今天运行它需要大约15分钟时间:

select SRDtoday.*
from SRD as SRDtoday
left join (select * from SRD where convert(date, dt) = convert(date, getdate())) as SRDyesterday ON (SRDtoday.Identifier = SRDyesterday.Identifier)
where convert(date, SRDtoday.dt) = convert(date, getdate())

当我查看执行计划时,它看起来像今天之前正在进行索引搜索,但是当我今天在查询中使用时,它正在进行索引扫描

我尝试过删除并重建索引,但这没有用。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您应该避免将动态/转换或任何类型的动态应用到整个列。当您这样做时,SQL必须将转换应用于每一行,无论它是否需要,然后才能检查相等/不等。通常,这会导致索引未被使用或未正确使用。

更好的方法是更改​​条件以适合数据类型,而不是适合条件的数据类型。

Ex而不是

WHERE CONVERT(DATE, DT) = '2016-09-02'

你可以这样做:

WHERE DT >= '2016-09-02' AND DT < '2016-09-03'

那就是说,这是我建议的改变:

declare @myDate DATETIME
set @myDate = convert(datetime,convert(date,getdate()))


select SRDtoday.*
from SRD as SRDtoday
left join (select * 
           from SRD 
           where dt >= @myDate and dt < DATEADD(DD,1,@myDate)) as SRDyesterday 
   ON (SRDtoday.Identifier = SRDyesterday.Identifier)
where SRDtoday.dt >= @myDate and SRDtoday.dt < DATEADD(DD,1,@myDate)