DATEADD在存储过程的WHERE子句中的神秘行为

时间:2012-07-17 16:27:56

标签: sql performance datetime stored-procedures sql-server-2000

这是我遇到的问题。我查询的表有1.7亿行。我编写了一个存储过程来对表中的最新条目进行简单查询。当我用这样的硬编码字符串写WHERE子句时:

SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > '2012-07-17 10:10:35.477'

非常快。不到一秒钟。 StartTime位于非聚集索引中。

然而,我真正想要的是:

DECLARE @fifteenMinutesAgo datetime;
SET @fifteenMinutesAgo = DATEADD(n , -15 , GETDATE());

SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > @fifteenMinutesAgo

问题是,当我运行第二个查询时,大约需要3分钟!

所以我开始乱搞并疯狂搜索。我认为它可能是一个数据类型问题所以我尝试了各种CAST和CONVERT并且没有成功。我尝试使用OPTIMIZE FOR,但意识到它不适用于此版本的SQL。我检查了StartTime的数据类型;它的类型为datetime

我尝试的另一件事,非常奇怪,是:

DECLARE @fifteenDaysAgo datetime;
SET @fifteenDaysAgo = DATEADD(d , -15 , GETDATE());

SELECT top 500 a.field1 , a.field2, a.field3
FROM database..hugeTable a( nolock )
WHERE a.StartTime > @fifteenDaysAgo

我将其从搜索最后15分钟更改为过去15天。神奇的是它再次超级快!不到一秒钟。

这让我相信SQL在某种程度上难以比较时间?它不需要查看TIME的{​​{1}}部分,看它是否适合比较语句?我不知道。在这里,我正在抓住稻草。

所以我的问题是,如何才能让这个速度相当快,并保持datetime动态?

1 个答案:

答案 0 :(得分:2)

您的程序看起来有“parameter sniffing”问题。 WITH RECOMPILE选项应该有帮助