我在Stackoverflow上看到了这篇帖子。第一个回答中提到聚簇索引包含表中所有的数据,而非聚簇索引仅包含列和聚簇索引或堆(没有聚簇索引的表)上的行的位置。非聚簇索引如何包含聚簇索引的位置?它只包含按节点排序的列值,并且每个节点指向具有该节点值的行,对吗?
我在Stackoverflow上看到了这篇帖子。第一个回答中提到聚簇索引包含表中所有的数据,而非聚簇索引仅包含列和聚簇索引或堆(没有聚簇索引的表)上的行的位置。非聚簇索引如何包含聚簇索引的位置?它只包含按节点排序的列值,并且每个节点指向具有该节点值的行,对吗?
CREATE INDEX
语句中定义的列,以及它具有组成聚集索引的列(如果存在)。如果您只关心该值-那么您只需返回该值。
或者非聚集索引可能还具有一些包含的列(在叶级别页面中),并且通过这些列,可以满足查询(请求的所有列都存在),因此您将获得所请求的值。
或者您想要的值不全部在非聚集索引叶级别页面中(如果您一直使用SELECT *
,那就尤其如此),然后查询执行程序必须从非聚集索引中获取聚集键值,并返回到聚集索引,执行所谓的键查找,通过聚集索引进行搜索,并找到关联的数据页,其中存储了完整的行->现在,查询执行程序可以返回您所请求的值。
有一个非常好的解释,请参见这篇博客文章。它说:
在非聚集索引中:
....
2.b. 如果表具有聚集索引,或者索引位于索引视图上,则行定位器是该行的聚集索引键。 SQL Server通过使用存储在非聚集索引的叶子行中的聚集索引键,在聚集索引中搜索以检索数据行。
或者查看关于SQL Server索引的整个系列中的这篇博客文章, 它还解释了存储在非聚集索引叶级页面中的“书签”。
很容易就能想象成这样:
假设你有一张客户表,例如customer(id、name、age、adress)。在这个表上,你有一个按年龄排序的聚集索引。这意味着你的数据在硬盘上是按年龄排序的。当你想进行范围查询时,这非常有利,比如:
SELECT * FROM customer WHERE age > 18;
a
上定义了非聚集索引,并且在列b
上定义了聚集索引,那么将会有两个独立的结构。聚集索引将按照列b
中的值的顺序对行进行排序,然后非聚集索引将使用指向数据的B树来排列列a
中的值(按照列b
中的值的顺序进行排序)。非聚集索引如何适应另一列b
? - SexyBeastSELECT *......
),则使用“b”值来进行键查找,以便在聚集索引中查找实际的数据页并返回查询的值。 - marc_s