使用DATEADD添加0分钟

and*_*a77 7 sql sql-server

我正在寻找一些在我的数据库中进行性能调优的机会,并且我遇到了一个带有此where子句的select语句:

WHERE GETDATE() > DATEADD(mi,0,[TimeStamp])
Run Code Online (Sandbox Code Playgroud)

我的问题是,以这种方式使用DATEADD是否有意义?我不明白为什么开发人员不会简单地使用它:

WHERE GETDATE() > [TimeStamp]
Run Code Online (Sandbox Code Playgroud)

Bog*_*ean 4

[1] WHERE GETDATE() > [TimeStamp]| WHERE Expression > Column| WHERE Column < Expression是 SARG 可谓词,这意味着 DBMS(例如 SQL Server)可以使用Index Seek(或Index Seek + Key|RID Lookup) 作为执行计划,以便快速查找并返回所需的行。

[2] WHERE GETDATE() > DATEADD(mi,0,[TimeStamp])| WHERE Expression > ScalarFunction(Column)| WHERE ScalarFunction(Column) < Expression不是 SARG 谓词,这意味着即使[Timestamp]DBMS 上有适当的索引也无法使用Seek. 相反,Table|Index|Clustered Scan将使用(通常但并非总是)性能低于Index Seek(至少对于 OLTP 系统)的运算符。

因此,即使存在正确的索引,也会在生成执行计划时强制使用数据访问运算符DATEADD(mi,0,[TimeStamp])Scan如果没有DATEADDDBMS,则可能使用的Seek运算符对于查询参数的某些/大多数值来说不是最佳选择。*

我会测试这两种解决方案(有和没有DATEADD(MINUTE, 0, ...)),看看性能方面是否有任何差异。

注意#1:为了强制扫描,SQL2008R2引入了FORCESCAN表提示(SQL2008也带有FORCESEEK表提示)(参考资料)。

注意#2:基本上,应用于[Timestamp]列 ( DATEADD(mi,0,[TimeStamp])) 的此函数也会在查询编译/查询优化期间产生影响,因为无法使用列统计信息。相反,因为操作不是=预定义的,所以使用的选择性将为 33%(据我从视频演示中记得 - 这不是官方/来自文档)。