【问题标题】:Does the SQL Server clustered index replace the RID lookup "index"SQL Server 聚集索引是否替换 RID 查找“索引”
【发布时间】:2011-04-12 07:01:31
【问题描述】:

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

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

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

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

【问题讨论】:

  • 您是从执行计划还是从哪里获得这些序列的?

标签: sql-server clustered-index


【解决方案1】:

是的,你已经很清楚了。

当您拥有聚集索引时,任何非聚集索引也将包含聚集索引中的列作为它们对实际数据的“查找”。

如果您在非聚集索引中搜索值,并且需要访问基础数据的剩余列,则 SQL Server 会从该非聚集索引中执行“书签查找”(或“键查找”)索引到聚集索引(在叶级节点中包含数据本身)。使用聚集索引,您不再需要 RID - 因此,如果 RID 更改(当数据从一页移动到另一页时),您不必更新所有索引页。

书签查找是相当昂贵的操作,因此您可以通过 INCLUDE 语句向非聚集索引添加额外的列。有了这个,您的非聚集索引将在其叶级页面上包含那些额外的列,如果您只需要包含在该数据集中的列,则可以从非聚集索引本身满足您的查询(即情况下,它被称为“覆盖索引”),您可以为自己节省一系列书签查找。

【讨论】:

  • 很好的回答谢谢,尤其是我以前没有遇到过的关于 INCLUDE 的提示。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    当一个表在 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 而是以聚集索引的聚集键“终止”?对吗?

    是的,有一些小的更正:

      1234563
    • 如果二级索引覆盖了聚集索引的某些列,则只有聚集键的缺失部分作为行指针追加。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 2018-06-27
      • 1970-01-01
      • 2012-10-01
      相关资源
      最近更新 更多