为什么DATEADD会降低SQL查询的速度?

时间:2014-02-27 07:53:49

标签: sql-server performance tsql

在我的SQL Server查询中,我尝试获得2秒的数据范围:

DECLARE @runtime AS datetime
SELECT @runtime = '2014-02-15 03:34:17'

SELECT Application FROM commandcip 
WHERE 
    commandname = 'RunTestCase' AND 
    (createdate BETWEEN DATEADD(s, -1, @runtime) AND DATEADD(s, 1, @runtime))

此命令非常慢,需要几分钟,基于性能分析器的估计子树成本为2800。

另一方面,如果我手动计算范围,查询速度非常快(估计子树成本 = 0.5,查询时间<1秒):

SELECT Application FROM commandcip 
WHERE 
    commandname = 'RunTestCase' AND 
    createdate BETWEEN '2014-02-15 03:34:16' AND '2014-02-15 03:34:18'

我验证了两个命令都返回了正确的数据。我验证了我的DATEADD命令返回正确的日期。我还尝试尽早将DATEADD提升一步(分为变量@mindate@maxdate),但这并没有帮助。

如果不手动计算范围,我应该如何加速第一次查询?

3 个答案:

答案 0 :(得分:3)

对于createdate BETWEEN '2014-02-15 03:34:16' AND '2014-02-15 03:34:18',可以在列统计信息中查找文字值,以估算匹配的行数。

除非您使用option (recompile),否则不会嗅探变量的值,因此SQL Server将使用启发式方法来猜测数字。

据推测,使用第一个数字得出的计划与使用第二个数字的计划不同。

e.g。一个估计较少的行并使用非覆盖索引查找,另一个估计完全扫描,因为估计的行数高于tipping point,此选项被认为更便宜。

答案 1 :(得分:0)

比较左侧的功能就像是SQL Server的黑盒子。你总是要尝试将功能移到右边

为了方便开发人员,添加了“between”关键字。查询优化器始终将其重写为双重比较。之间并不比双重比较慢。 您可以在使用时查看此操作:查询顶部的SET STATISTICS PROFILE ON enter image description here

答案 2 :(得分:-1)

查询执行时间取决于很多因素。

更多,在这种情况下,对WHERE子句进行操作,对于每个元组,通常有点慢。 我的建议是改进你的选择。 例如,添加2个变量,@ start datetime = DATEADD(s,-1,@ runtime),@ end datetime = DATEADD(s,1,@ runtime),并替换DATEADD(s,-1,@ runtime)和DATEADD (s,1,@ runtime)。 另一个,有时介于之间比双重比较慢(&gt; =,&lt; =)。