使用变量时的查询性能

时间:2016-07-13 20:31:03

标签: sql sql-server

我有一张大约有2亿行的表格。该表包含许多列,但目前只有主键和非聚集索引基于索引的datetime列。

第一个查询将在不到一秒的时间内返回零行。

SELECT *
FROM GenericTable
WHERE GenericDate > '01-01-1753' AND GenericDate <= '01-29-1753'

此查询需要花费相当长的时间才能返回零行,大约两分钟。

DECLARE @startDate DATETIME, @endDate DATETIME

SET @startDate = '01-01-1753'
SET @endDate = '01-29-1753'

SELECT *
FROM GenericTable
WHERE GenericDate > @startDate AND GenericDate <= @endDate

使用包含数据的日期范围,性能会好一点吗?第一个查询将在不到一秒的时间内返回1000行,第二个查询仍需要30秒或更长时间才能返回相同的数据。

编辑:我还告诉我执行计划,第二个查询没有使用索引?

第一次查询:

Select <- Nested Loops (Inner Join) - 0% <- Index Seek (NonClustered) - 0%
                                         <- Key Lookup (Clustered) - 100%

第二次质疑:

Select <- Parallelism (Gather Streams) - 10% <- Clustered Index Scan (Clustered) - 90%

1 个答案:

答案 0 :(得分:5)

执行计划缓存和参数是一个众所周知的问题 嗅探。

引自this article

  

前段时间我写了关于参数嗅探,SQL的情况   编译和缓存适合于a的执行计划   参数的某个值,但对其他值不是最佳的。   参数嗅探的另一面是 - 当优化器时   根本无法闻到。

     

当批次提交给优化器时,任何值都是   参数(来自存储过程,自动参数化或   sp_executesql)为优化器所知。任何价值也是如此   SQL语句中使用的常量。局部变量的值,   但是,不是。

     

当where子句中使用的变量值未知时,优化器不知道使用什么值来估计数字   受影响的行。因此,它不知道表中有多少行   将满足条件。