包含列或复合索引的索引

Joh*_*lan 3 sql-server indexing

查看 SQLServer 上缺少的索引 DMV,它建议我添加以下索引:

CREATE INDEX [IXFoo] ON [a].[b].[MyTable] ([BarFlag]) INCLUDE ([BazID])

有两件事让我感到困惑。

  • [BarFlag]是一个位域。几乎没有高度选择性,为什么要在位字段上放置索引?
  • 在这种情况下为什么不使用复合索引。: CREATE INDEX [IXFoo] ON [a].[b].[MyTable] ([BarFlag],[BazID])

我想我没有INCLUDE正确理解关键字。我已经查看了msdn的解释,但我仍然不清楚。

有人可以解释为什么在组合中建议使用此索引INCLUDE并向我解释关键字吗?

mar*_*c_s 5

主要区别在于:

  • 如果您在 上创建复合索引(BarFlag, BazID),那么您的索引将包含索引 b 树所有级别上的两个值;这意味着,查询分析器在做出决定时也有机会使用这两个值,这可以支持在 WHERE 子句中指定两列的查询

  • 如果您(BarFlag)仅在 include上创建索引(BazID),则您的索引将仅包含BarFlag索引 b 树所有级别的值,并且仅在叶级别,即“最后”级别,也将BazID包含包含的值。这些BazID值不能用于选择数据 - 它们仅存在于索引叶级别以供查找。

仅对于一个不太重要的 INT 和 BIT,但如果您正在处理一VARCHAR(2000)列,则无法将其添加到实际索引中(每个条目最多 900 字节) - 但您可以包含它。

如果您选择这两个值,那么在索引中包含一列会很有用 - 然后如果 SQL Server 找到匹配的BarFlag,它可以BazID在索引本身的叶级节点中查找相应的值,并且可以保存自己返回实际数据页(“书签查找”)以从数据页中获取该值。这可以极大地提高性能

你是对的 - 在BarFlag(BIT)上建立一个索引真的没有意义 - 再说一次,DMV 只建议索引 - 你不应该盲目地遵循它的所有建议 - 你仍然需要思考和考虑是否这些是很好的建议(或不是)。