【问题标题】:T-SQL datetime variable behaves differently than getdate()T-SQL 日期时间变量的行为不同于 getdate()
【发布时间】:2014-05-10 17:13:39
【问题描述】:

需要重做一个使用当前日期 (getdate()) 选择项目的查询(大量内连接,大约有 20 个表)。

请求是允许用户指定某个日期而不是getdate()。 将变量@mydate 声明为datetime = getdate(),并将查询中的所有getdate() 替换为@mydate

查询执行时间从 10 秒跃升至 6 分钟!并且执行计划完全改变了。

花了很长时间调查为什么会发生这种情况,最后是

option (optimize for (`@mydate = '2000-01-01'`))

成功了——尽管在我看来这似乎是不必要的,因为我的变量定义看起来像

declare @mydate as datetime = getdate()

并且不应该为变体解释留出空间?

我的问题:

T-SQL 中的一般建议是在所有查询中指定变量示例值还是只是 datetime 一个(可能,根据我的经验,这不是一般问题)问题?

【问题讨论】:

  • 一般来说,值和数据类型都不是问题,包括datetime。这是您的具体情况,我们无法确定,因为您几乎没有向我们提供任何信息。

标签: sql-server tsql datetime execution-time


【解决方案1】:

这与变量恰好是日期时间变量这一事实无关,它是查询优化器逻辑的产物。

当您使用常量(或 getdate())时,优化器会在确定可用于进行最佳查询的索引等时了解如何使用该表达式。

正如您所发现的,优化选项基本上恢复了已知的“常量”查询版本,因此它会再次快速运行。

多年来,我已经多次遇到这个问题,解决方案并不总是显而易见的——也就是说,您不能只是自动使用选项优化来修复它。它以多种方式显示,如 this article 有问题的执行计划所示。

添加

我进行了更多搜索,发现 Constant Folding and Expression Evaluation During Cardinality Estimation 与您的具体问题特别相关。

【讨论】:

  • 添加了关于常量折叠的文章
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 2010-10-07
  • 2018-05-16
相关资源
最近更新 更多