13

当一个表在 SQL Server 中具有聚集索引时,这是否意味着所有索引查询都将通过聚集索引进行?

例如,如果我有一个带有单个非聚集索引(索引一列)的表并通过该列搜索一行,它将执行Index Seek -> RID -> Data row lookup -> Result

但是,如果我在不同的列上添加聚集索引,那么相同的查询将执行以下操作Index Seek -> Extract clustering key -> Clustered index seek -> Results

这对我来说意味着非聚集索引不再以叶处的 RID 而是以聚集索引的聚集键“终止”?那正确吗?

4

3 回答 3

13

Yes, you got it pretty much figured out.

When you have a clustered index, then any non-clustered index will also include the column(s) from the clustered index as their "lookup" into the actual data.

If you search for a value in a non-clustered index, and you need to access the remaining columns of the underlying data, then SQL Server does a "bookmark lookup" (or "key lookup") from that non-clustered index into the clustered index (which contains the data itself, in the leaf-level nodes). With a clustered index, you don't need the RID's anymore - and thus you don't have to update all your index pages if a RID changes (when data gets moved from one page to another).

Bookmark lookups are rather expensive operations, so you can add additional columns to your non-clustered indices via the INCLUDE statement. With this, your non-clustered index will contain those additional columns on its leaf-level pages, and if you only need columns that are contained in that set of data, your query can be satisfied from the non-clustered index itself (in that case, it's called a "covering index") and you can save yourself a series of bookmark lookups.

于 2010-09-14T17:14:44.613 回答
1

不,不是每个查询都会使用聚集索引。如果查询被非聚集索引“覆盖”(查询所需的所有列都包含在 NC 索引中),那么 SQL Server 将只需要读取这些索引页而不执行书签查找。事实上,优化器通常会尽可能使用覆盖 NC 索引,因为 NC 索引通常小于聚集索引,因此通常扫描速度更快。

于 2010-09-14T20:12:55.457 回答
1

当一个表在 SQL Server 中具有聚集索引时,这是否意味着所有索引查询都将通过聚集索引进行?

不。

如果查询仅使用二级索引和/或聚集索引所涵盖的字段,则二级索引可能(并且很可能会)是首选。

CREATE TABLE test (id INT NOT NULL PRIMARY KEY, value1 INT NOT NULL, value2 INT NOT NULL)

CREATE INDEX ix_test_value2 ON test (value2)

SELECT  value2, id
FROM    test

上面的查询很可能会使用ix_test_value2,因为它包含查询所需的所有信息,但大小更小。

这对我来说意味着非聚集索引不再以叶处的 RID 而是以聚集索引的聚集键“终止”?那正确吗?

是的,有一些小的更正:

  • 如果聚集索引是非唯一的,则二级索引中的行指针由聚集键加上一个特殊的隐藏列uniquiefier(实际上,该列也附加到聚集索引)组成。

  • 如果二级索引覆盖了聚集索引的某些列,则仅将聚集键的缺失部分附加为行指针。

  • 如果声明了二级索引UNIQUE,则聚集键仅附加到二级索引的叶级记录。

于 2010-09-14T20:23:16.160 回答