用DATEADD添加0分钟
我正在寻找一些在数据库中进行性能调优的机会,并且我已经通过where子句发现了一条select语句:
WHERE GETDATE() > DATEADD(mi,0,[TimeStamp])
我的问题是,以这种方式使用DATEADD是否合理? 我不明白为什么开发人员不会简单地使用它:
WHERE GETDATE() > [TimeStamp]
[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系统)具有(通常而言并不总是 )性能较低的Index Seek
。
所以即使有合适的索引DATEADD(mi,0,[TimeStamp])
也会在执行计划生成时强制使用Scan
数据访问操作符。 没有DATEADD
DBMS可以使用一个Seek
运算符,它不能成为查询参数的某些/大部分值的最佳选择。*
我会测试两种解决方案(有和没有DATEADD(MINUTE, 0, ...)
),以查看在性能方面是否有任何差异。
注意#1:为了强制扫描SQL2008R2引入的FORCESCAN
表提示(SQL2008自带FORCESEEK
表提示)(引用)。
注#2:基本上这个函数应用于[Timestamp]
列( DATEADD(mi,0,[TimeStamp])
)在查询编译/查询优化期间也会有影响,因为不能使用列统计信息。 相反,因为操作不是=
预定义的选择使用将是33%(据我记得,从视频演示文稿 - 它不是官方/从文档)。
我认为编写这段代码时开发人员犯了一个错误。
DATEADD
可以降低性能,因为不会使用索引,并且作者不担心性能。https://www.sqlservercentral.com/Forums/608017/dateAdd-inside-where-clause
如果过滤器值可以改变,最好写
[TimeStamp] < DATEADD(MINUTE, 0, GETDATE())
在这种情况下,您不仅可以处理添加0分钟时的情况,而且可以处理另一个情况(例如, DATEADD(MINUTE, 10, GETDATE())
)
上一篇: Adding 0 Minutes with DATEADD
下一篇: rjava dependent package installation Segmentation fault (core dumped)