【问题标题】:How does SQL covering index work?SQL 覆盖索引是如何工作的?
【发布时间】:2018-06-12 01:12:20
【问题描述】:

我知道,当我们使用覆盖索引时,sql server 在执行计划中只使用索引查找(非聚集)或索引扫描(非聚集)运算符,而不通过查找运算符检索数据。但是为什么不能在聚集索引中查找值呢?非聚集索引不在叶级存储数据,因此无论它包含多少列,它都必须要求聚集索引返回数据行,因此它应该是执行计划中的查找运算符。我对吗?我看过https://www.red-gate.com/simple-talk/sql/learn-sql-server/using-covering-indexes-to-improve-query-performance/和其他文章,但没有任何解释。

【问题讨论】:

    标签: sql-server indexing


    【解决方案1】:

    所有级别的任何索引都存储定义该索引键的列的值。此外,在非聚集索引的叶级别,叶存储任何附加列的值,这些列是聚集索引键1 的一部分,而不是非聚集索引的一部分。聚集索引键,因为这是随后执行聚集索引查找的方式。

    如果查询需要检索的唯一列要么是非聚集索引键的一部分,要么是聚集索引键的一部分,那么我们已经通过导航非聚集索引键获得了所有这些列值。聚集索引。

    一般来说,查询不会尝试检索,只尝试检索特定列中的行值。


    打个比方,假设您正在对整个城镇进行人口普查,并存储所有数据和实体卡片。这些卡片包含此人的姓名、地址、出生日期、当前职业等。进一步假设每个人都有一个唯一的地址,因此您决定将所有这些卡片按地址顺序存储在一个大文件中。这是您的聚集索引。

    您经常希望根据姓名定位人员。因此,您创建了另一组索引卡,用于告诉您,对于姓氏和名字的任何特定组合,具有该名称的人所居住的所有地址。您将这些卡片放在第二个盒子文件中,并按姓氏、名字值对它们进行排序。这是您的非聚集索引。

    最后,假设您的任务是找出所有姓氏为Radish 的人居住的街道。您显然可以使用您的非聚集索引来识别所有姓氏为Radish 的人。但请记住,此二级索引中的卡片会为您提供这些人的地址。如果我们唯一的任务是识别他们的街道,那么我们已经掌握了这些信息。我们没有必要去查找所有原始人口普查卡,其中包含我们没有被要求提供的各种信息,只是为了完成这个查询。


    1自 2012 年以来,在索引定义的 INCLUDE 子句中标识的任何其他列。

    【讨论】:

    • 来自 Technet technet.microsoft.com/en-us/library/ms177484(v=sql.105).aspx:“非聚集索引的叶层由索引页而不是数据页组成...SQL Server 通过使用聚集索引搜索聚集索引来检索数据行存储在非聚集索引的叶行中的键。”请看页面底部的插图。非聚集索引没有数据行,只有索引行。
    • @lukaszwinski - 它不需要 行 - 仅来自特定列的值。如果这些值已经包含在索引结构中,则无需为了再次获取这些值而去查找完整的行。这就是覆盖指数的全部意义所在。如果每个索引使用都需要执行聚集索引查找,那么覆盖索引(和INCLUDE)的概念将毫无意义。
    • @lukaszwinski - 如果您从您的页面点击链接到Index with Included Columns,则可以确认 - “性能提升是因为查询优化器可以定位索引中的所有列值;表或集群索引数据未访问..."
    • 包含选项从一开始我就很清楚。当我们没有使用“包含”选项创建非聚集索引但查询被覆盖时,我不明白覆盖是如何工作的。
    • @lukaszwinski - 因为INCLUDE 所做的只是扩展已经包含聚集索引键的功能。
    【解决方案2】:

    由于覆盖索引包含了查询的所有SELECT项,所以不需要去表数据尝试从数据文件中读取。您尝试读取的数据已包含在 Covering Index 中。

    所以你要么通过索引扫描读取所有覆盖索引,要么通过索引查找直接读取。

    【讨论】:

    • 你知道非聚集索引架构和b-tree结构吗?非聚集索引因为它的设计不能直接返回数据——它将RID或聚集索引键保持在叶级,而不是查询的数据行。跨度>
    • 上次我在一个表中查询一个只在索引中的值,它在查询计划中唯一使用的就是索引
    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    相关资源
    最近更新 更多