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

爸爸

我从来没有真正理解过这两个索引之间的区别,有人可以解释一下区别是什么(性能方面,在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结构,由“索引页”(根目录和所有中间页)和“索引数据页”(仅叶子页)组成。

请注意,请勿将“索引数据页”与存储大多数实际数据列的“数据页”(聚集索引的叶页)混淆。

  • 仅索引列存储在索引页面上。
  • 通过在该INCLUDE节中放置一些列,每个索引键上存储的数据更少。
  • 这意味着需要更少的页面来保存索引键。(这使得更容易将这些常用页面在内存中的缓存时间更长。
  • 并且树中的级别可能更少。在这种情况下,性能提升可能会更大,因为每个树级别遍历都是另一个磁盘访问。

使用索引时,索引键用于在索引页面中导航到正确的索引数据页面。

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

需要注意的一些事情有望解决您的一些困惑:

  • 如果索引的关键字和查询中的过滤器的选择性不够,则该索引将被忽略(无论您的INCLUDE列中有什么内容)。
  • 您创建的每个索引都有INSERT和UPDATE语句的开销。对于“更大”的索引更是如此。(更大也适用于INCLUDE列。)
  • 因此,尽管从理论上讲您可以使用include列创建大量大索引来匹配访问路径的所有排列:这会适得其反。

值得注意的是,在将INCLUDE列添加为功能之前:

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

注意:有一点很重要。INCLUDE如果您习惯于始终将查询编写为,这通常会导致您从索引列中获得零收益SELECT * ...通过返回所有列,您基本上可以确保在任何情况下都需要书签查找。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章