使用DATEADD添加0分钟

时间:2017-06-20 13:19:00

标签: sql sql-server

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

WHERE GETDATE() > DATEADD(mi,0,[TimeStamp])

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

WHERE GETDATE() > [TimeStamp]

2 个答案:

答案 0 :(得分:4)

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

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

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

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

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

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

答案 1 :(得分:0)

我认为编写此代码时开发人员犯了错误。

DATEADD会降低性能,因为不会使用索引,作者也不会担心性能问题 https://www.sqlservercentral.com/Forums/608017/dateAdd-inside-where-clause

如果过滤值可以改变,那么写

会更好
[TimeStamp] < DATEADD(MINUTE, 0, GETDATE())

在这种情况下,您不仅可以处理添加0分钟的情况,还可以处理其他情况(例如DATEADD(MINUTE, 10, GETDATE())