需要重做一个查询(大量内部连接大约20个表),使用当前日期(getdate()
)来选择项目。
请求允许用户指定一个特定的日期而不是getdate()
。将变量@mydate
声明为datetime = getdate()
,并将查询中的所有getdate()
替换为@mydate
。
查询执行时间从10秒上升到6分钟!执行计划完全改变了。
花了很长时间调查为什么会发生这种情况,最后得出
option (optimize for (`@mydate = '2000-01-01'`))
做到了这一点——尽管对我来说它看起来不应该是必要的,因为我的变量定义看起来像
declare @mydate as datetime = getdate()
不应该给不同的解释留有余地吗?
我的问题:
在T-SQL中是否建议在所有查询中指定变量示例值,或者仅datetime
a(可能的,这不是我经验中的一般问题)问题?
这与变量恰好是日期时间变量这一事实无关,它是查询优化器逻辑的工件。
当你使用常量(或getdate())时,优化器知道如何在确定索引等时使用该表达式来进行最优查询。
正如您所发现的,optimize for选项实际上恢复了查询的已知"常量"版本,因此它将再次快速运行。
在过去的几年里,我已经碰到过这个问题好几次了,解决方案并不总是显而易见的——也就是说,你不能自动使用优化选项来修复它。它以多种方式出现,如本文在有问题的执行计划中所见。
添加我做了一些更多的搜索,发现常量折叠和表达式评估在基数估计期间特别与您的特定问题相关。