我在Stackoverflow中遇到了this帖子 . 第一个答案提到像 A clustered index has all the data for the table while a non clustered index only has the column + the location of the clustered index or the row if it is on a heap (a table without a clustered index). 非聚集索引如何具有聚集索引的位置?它只包含作为B树中的节点排序的列值,每个节点都固定到列具有该节点值的行,对吧?
2 回答
假设你正在谈论 SQL Server 并且还假设你的 table 上有一个聚集索引(你应该这样做) .
然后,非聚簇索引具有您在
CREATE INDEX
语句中定义的列, plus 它具有构成聚簇索引的列(如果存在) .该聚类键值是实际数据所在位置的“指针” .
如果查询执行程序通过非聚集索引查找值并找到匹配项,那么
either 这个 Value 就是你所关心的 - 那么你只需要回到那个 Value
or 非聚集索引也可能包含一些列(在叶级页面中),并且可以满足查询(请求的所有列都存在),这样您就可以获得所需的值
or 那么你想要的值并不都在非聚集索引叶级页面中(如果你一直都是
SELECT *
则尤其如此)然后查询 Actuator 必须从非聚簇索引中获取聚类键值,然后返回到聚类索引,执行所谓的键查找,搜索聚类索引,并找到存储完整行的关联数据页面 - >现在查询执行程序可以返回您要求的值有一个很好的解释 - 见this blog post here . 它说:
或者参见this blog post in a whole series on SQL Server indexes,它解释了存储在非聚集索引叶级页面中的"bookmarks" .
这很容易想象:
您有一个客户表,例如客户(身份证,姓名,年龄,地址) . 在这张 table 上你有一个 clustered index 年龄 . 这意味着您的数据在硬盘驱动器上是 sorted by age . 当您想要进行范围查询时,这非常有用:
然后,只需几次连续读取即可从硬盘驱动器中获取数据 . 如果索引是非聚集的,则必须为每个匹配的客户元组进行一次磁盘访问(包括数据搜索) .
也许对于您的应用程序,您还需要通过id访问用户 . 这意味着如果没有id的附加索引,您将需要 run over the entire file 来查找特定ID,因为它按年龄排序而您没有索引!为避免这种情况,请创建 second index on id . 现在,您可以在此索引中搜索id,并且索引的叶子(包含您要查找的客户)指向光盘中(按年龄聚集)数据中的位置,您可以在其中找到元组 . 通过这种方式,您不必读取整个表需要更少的光盘访问(通常2用于索引查找1以获取元组) .
编辑:我没有看到你在谈论相同的专栏 . 我可以想象的一件事是,由于上述原因,您在一列上执行了一个聚簇索引,而另一列 combined index 和另一列例如 . 这对于 index-only lookup 非常有用,这里您拥有索引中的所有必需属性,并且根本不需要进行页面提取 . 另一个原因是为范围查询提供了一个聚类B -Index,为相等查询提供了一个Hash-Index . 但我认为这里的好处可以忽略不计 .
希望这有帮助!