我有一张大约有2亿行的表.该表包含许多列,但目前只有主键和非聚簇索引基于索引的datetime列.
第一个查询将在不到一秒的时间内返回零行.
SELECT *
FROM GenericTable
WHERE GenericDate > '01-01-1753' AND GenericDate <= '01-29-1753'
Run Code Online (Sandbox Code Playgroud)
此查询需要过长的时间才能返回零行,大约两分钟.
DECLARE @startDate DATETIME, @endDate DATETIME
SET @startDate = '01-01-1753'
SET @endDate = '01-29-1753'
SELECT *
FROM GenericTable
WHERE GenericDate > @startDate AND GenericDate <= @endDate
Run Code Online (Sandbox Code Playgroud)
使用包含数据的日期范围,性能会好一点吗?第一个查询将在不到一秒的时间内返回1000行,第二个查询仍需要30秒或更长时间才能返回相同的数据.
编辑:我也告诉我执行计划,第二个查询不使用索引?
第一次查询:
Select <- Nested Loops (Inner Join) - 0% <- Index Seek (NonClustered) - 0%
<- Key Lookup (Clustered) - 100%
Run Code Online (Sandbox Code Playgroud)
第二次查询:
Select <- Parallelism (Gather Streams) - 10% <- Clustered Index Scan (Clustered) - 90%
Run Code Online (Sandbox Code Playgroud)
这是执行计划缓存和参数嗅探的一个众所周知的问题.
引用本文
前段时间我写了一篇关于参数嗅探的文章,其中SQL编译并缓存了一个适合某个参数值的执行计划,但对其他值不是最佳的.参数嗅探的另一面是 - 当优化器根本无法嗅探时.
将批处理提交给优化程序时,优化程序将知道任何参数的值(来自存储过程,自动参数化或sp_executesql).SQL语句中使用的任何常量的值也是如此.但是,局部变量的值不是.
当where子句中使用的变量的值未知时,优化器不知道使用什么值来估计受影响的行数.因此,它不知道表中有多少行会满足条件.
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |