考虑以下三个问题:
select sampleno from sample
where markupdate > '1/1/2010'
select sampleno, markupdate from sample
where markupdate > '1/1/2010'
select sampleno, markuptime from sample
where markupdate > '1/1/2010'
sampleno
和markupdate
是索引字段(sampleno
是主键)
markuptime
未编入索引
查询1和2大约需要1秒才能运行(返回237K行)。查询3在3分钟后仍在运行。
为什么在SELECT子句中包含非索引字段会导致性能下降?
这是一个SQL 6.5数据库。
答案 0 :(得分:5)
表的数据(基本上:所有列)存储在聚集索引中。聚簇索引是一个二叉树,允许对索引列进行二进制搜索。它是特殊的(聚集的),因为它包含叶级别的所有其他列。通常,聚簇索引也是主键。在你的情况下,它是:
(sampleno) include (markupdate, markuptime, ...)
非聚集索引包含索引列和(在叶级别)聚簇索引。使用非聚集索引时,数据库必须查找聚簇索引中的所有其他列。该过程称为查找。在您的情况下,(markupdate)
上的非聚集索引是:
(markupdate) include (sampleno)
此索引包含markupdate, sampleno
上查询的所有数据。这种指数的技术术语是覆盖指数。但是当您向查询添加markuptime
时,索引不再覆盖。它必须在聚集索引中查找markuptime
的值。查找是广泛的。
只有您的第三个查询需要查找。这就是你的第三个查询速度较慢的原因。