Sex*_*ast 6 sql-server clustered-index nonclustered-index
我发现当一个表同时具有聚集索引和非聚集索引(在不同的列上)时,叶级非聚集页,而不是指向数据行,指向聚集索引的节点,从那里另一个搜索用于查找数据行。这个额外的间接级别有什么意义?如果聚集索引有 8 个级别,那么从 NCI 叶页到 CI 根的间接访问将必须遍历这 8 个级别才能到达数据。为什么不把普通的RID存储在NCI的叶子页面中,这样我们就可以不用经过CI的索引结构就可以一次访问数据呢?
mar*_*c_s 10
这样做的原因是您的行的“固定”物理位置 - RID(或行标识符)可能(并且将会!)随着时间的推移而改变 - 想想当需要将行插入到表中的表中时发生的页面拆分已满的页面。
更新给定表上存在的所有非聚集索引中的那些 RID 很快变得既麻烦又是一个巨大的性能杀手。您的表上可能有 5、10、20 个非聚集索引,并且 SQL Server 必须扫描所有这些索引(基本上扫描整个索引、索引中的所有行,以及 10、20 次)并更新所有 RID。 .. 这不切实际 - 很快。
如果您将集群索引的值存储为“行指针”,则该值通常永远不会改变——而且绝对不需要在每次拆分页面时更新。是的,它确实涉及第二个索引查找操作 -键查找- 但是对于简单的场景,检索单行或几行,这仍然比其他任何操作都有效。
简单来说,当聚集索引中的数据物理移动(行转发、页面拆分、插入等)时,它涉及较少的 NC 索引条目的处理和移动。
大多数情况下,聚集索引条目只需要更改:而不是 NC 索引指针。通过使用 RID,您需要在 NC 索引上做更多的工作。
为了最小化查询中的这种查找,您需要使 NC 索引“覆盖”。例如,参见/sf/ask/97669281/#1395322