为什么在SELECT子句中使用非索引字段时性能会降低?

时间:2013-02-08 16:55:03

标签: sql-server

考虑以下三个问题:

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'

samplenomarkupdate是索引字段(sampleno是主键)

markuptime未编入索引

查询1和2大约需要1秒才能运行(返回237K行)。查询3在3分钟后仍在运行。

为什么在SELECT子句中包含非索引字段会导致性能下降?

这是一个SQL 6.5数据库。

1 个答案:

答案 0 :(得分:5)

表的数据(基本上:所有列)存储在聚集索引中。聚簇索引是一个二叉树,允许对索引列进行二进制搜索。它是特殊的(聚集的),因为它包含叶级别的所有其他列。通常,聚簇索引也是主键。在你的情况下,它是:

(sampleno) include (markupdate, markuptime, ...)

非聚集索引包含索引列和(在叶级别)聚簇索引。使用非聚集索引时,数据库必须查找聚簇索引中的所有其他列。该过程称为查找。在您的情况下,(markupdate)上的非聚集索引是:

(markupdate) include (sampleno)

此索引包含markupdate, sampleno上查询的所有数据。这种指数的技术术语是覆盖指数。但是当您向查询添加markuptime时,索引不再覆盖。它必须在聚集索引中查找markuptime的值。查找是广泛的。

只有您的第三个查询需要查找。这就是你的第三个查询速度较慢的原因。