【问题标题】:Mysterious behavior from DATEADD in WHERE clause of a stored procedure存储过程的 WHERE 子句中 DATEADD 的神秘行为
【发布时间】:2012-07-16 15:09:13
【问题描述】:

这是我遇到的问题。我正在查询的表有 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 很难比较时间?它不需要查看datetimeTIME 部分来查看它是否适合比较语句?我不知道。在这里,我抓住了稻草。

所以我的问题是,我怎样才能使这个速度相当快并且仍然保持我的 @fifteenMinutesAgo 动态?

【问题讨论】:

  • 您是否查看了两个查询之间的执行计划以了解执行中可能存在的差异?
  • 我应该把它包括在内。是的,执行计划是相同的。
  • 你可以尝试执行存储过程的慢版本WITH RECOMPILE选项,看看是否有帮助?
  • a1ex07,你成功了。它现在自动快速。请添加答案。同时,我将研究对 RECOMPILE 语句的性能影响。
  • 您是否真的使用 变量 作为示例代码所指示的参数或参数?

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


【解决方案1】:

您的程序似乎有“parameter sniffing”问题。 WITH RECOMPILE 选项应该会有所帮助

【讨论】:

  • 正如我在 cmets 中对问题所说的那样,我真的认为这就是问题所在。但是,自从阅读了您链接到的文章后,我意识到这不是问题所在。我没有使用参数,我使用的是变量。但是,不知何故,将WITH RECOMPILE 添加到我的 SP 使它快速了一段时间。我只是通过我的确切步骤按CTRL-Z返回以确保我正确运行它并且在测试您的建议时我没有以某种方式将硬编码的日期留在那里。还有其他想法吗?
  • 如果它不时有帮助,我怀疑统计信息没有正确更新,优化器使用了错误的执行计划。我不熟悉 SQLServer 2000;在 2005 年和 2008 年可以强制查询使用特定的执行计划,不确定 2000 年是否有这样的选项...
  • 另一个建议:如果您在存储过程的主体中使用条件,也有可能遇到与参数嗅探非常相似的问题 - 首次执行时编译的过程和创建的执行计划,然后它重用相同的计划。
  • 我最终在这个问题上花费了太多时间,所以我最终找到了解决方法。我最初是在寻找过去 15 分钟插入到这个庞大表中的数据,我知道当时输入的记录永远不会超过几千条,所以我只是查询了最底部的 10,000 条记录,然后运行了一个'outer'查询这些,按日期过滤。时间回到亚秒级。我不得不说我学到了很多关于“参数嗅探”的东西。感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 2015-01-29
  • 2014-01-24
  • 2013-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多