gpt4 book ai didi

sql - 具有包含列的索引,有什么区别?

转载 作者:行者123 更新时间:2023-12-03 07:27:37 24 4
gpt4 key购买 nike

我从来没有真正理解过这两个索引之间的区别,有人可以解释一下它们之间的区别是什么(性能方面,在db中如何看待索引结构,在存储方面如何)
包含的索引

CREATE NONCLUSTERED INDEX IX_Address_PostalCode  
ON Person.Address (PostalCode)
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
“普通”索引
CREATE NONCLUSTERED INDEX IX_Address_PostalCode  
ON Person.Address (PostalCode, AddressLine1, AddressLine2, City, StateProvinceID);

最佳答案

索引的内部存储使用B-Tree结构,由“索引页”(根目录和所有中间页)和“索引数据页”(仅叶子页)组成。

Note do not confuse "index data pages" with the "data pages" (leaf pages of clustered indexes) which store most of the columns of actual data.


  • 仅索引列存储在索引页面上。
  • 通过在INCLUDE节中放置一些列,每个索引键上存储的数据更少。
  • 表示保存索引键所需的页面更少。 (这样可以更轻松地将这些常用页面在内存中缓存更长的时间。)
  • 并且树中的级别可能更少。 (在这种情况下,由于每个树级别的遍历都是另一个磁盘访问,因此性能 yield 可能会更大。)

  • 使用索引时,索引键用于在索引页面中导航到正确的索引数据页面。
  • 如果索引包含INCLUDE列,则该数据将在查询需要时立即可用。
  • 如果查询要求索引键或INCLUDE列中都不可用的列,则需要对聚集索引中的正确行进行附加“书签查找”(如果未定义聚集索引,则需要堆)。

  • 需要注意的一些事情有望解决您的一些困惑:
  • 如果您的索引键和查询中的过滤器的选择性不够,则该索引将被忽略(不管INCLUDE列中包含什么)。
  • 您创建的每个索引都有INSERT和UPDATE语句的开销。对于“更大”的索引更是如此。 (更大也适用于INCLUDE列。)
  • 因此,尽管从理论上讲您可以创建带有包含列的多个大索引,以匹配访问路径的所有排列:这会适得其反。


  • 值得注意的是,在添加 INCLUDE列作为功能之前:
  • 这是常见的索引调整“技巧”,用于扩展索引的键以包括索引/过滤器中不需要的列。 (称为覆盖索引。)
  • 这些列通常在输出列中或作为对其他表的联接的引用列是必需的。
  • 这样可以避免臭名昭著的“书签查找”,但是具有使索引比严格必要的“更宽”的缺点。
  • 实际上,索引中较早的列通常已经标识了唯一行,这意味着如果没有“避免书签查找”的好处,那么额外包含的列将完全多余。
  • INCLUDE列基本上可以更有效地实现相同的好处。

  • NB Something very important to point out. You generally get zero benefit out of INCLUDE columns in your indexes if you're in the lazy habit of always writing your queries as SELECT * .... By returning all columns you're basically ensuring a bookmark lookup is required in any case.

    关于sql - 具有包含列的索引,有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41791413/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com