我有一个这样的查询:
SELECT col1
FROM MyTable
WHERE
DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
BETWEEN col2
AND col3
;
这给出了一个关于执行计划的工具提示,类似于:
是否dateadd
为查询中的每一行执行搜索谓词部分?或者 SQL Server 是否为整个查询计算一次值?
我有一个这样的查询:
SELECT col1
FROM MyTable
WHERE
DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
BETWEEN col2
AND col3
;
这给出了一个关于执行计划的工具提示,类似于:
是否dateadd
为查询中的每一行执行搜索谓词部分?或者 SQL Server 是否为整个查询计算一次值?
某些已知为运行时常量的函数会经历称为常量折叠的过程。当“折叠”一个常量时,表达式在查询执行的早期被评估,结果被缓存,并在需要时使用缓存的结果。查询中的表达式
DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))
是 AFAIK,一个运行时常量,因此每个查询只会折叠和评估一次。琐事:
RAND()
人们期望可展开的功能实际上是可折叠的,这导致了一些意想不到的行为。但是其他的,例如NEWID()
,不可折叠,并且会强制每行进行评估。执行计划很棒,但有时他们只是不告诉你真相。所以这里有一个基于性能测试的证明。
(和底线 - 没有为每一行评估表达式)
这是 OP 查询,运行大约需要 12 秒
该查询在执行前将日期存储在参数中,大约需要 12 秒的时间。
并且只是为了验证结果 -
这个查询在 col1 上进行计算,因此必须重新计算每一行的表达式,运行大约需要 30 秒。
所有查询都重复执行,显示大致相同的指标