包含列或复合索引的索引

时间:2011-03-02 10:19:01

标签: 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关键字吗?

2 个答案:

答案 0 :(得分:4)

主要区别在于:

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

  • 如果您在(BarFlag)上创建索引且仅包含(BazID),那么您的索引将仅包含索引b树的所有级别上的BarFlag值,并且仅在叶级别,“最后”级别,还将包含BazID的值。 BazID值不能用于选择数据 - 它们只是出现在索引叶级别以供查找。

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

如果选择这两个值,则索引中包含列可能很有用 - 如果SQL Server找到BarFlag的匹配项,它可以在叶子中查找相应的BazID值索引本身的级别节点,它可以保存自己返回实际数据页面(“书签查找”)以从数据页中获取该值。这可以大大提升绩效

你是对的 - 只有BarFlag(BIT)上的索引真的没有意义 - 再说一遍,DMV只建议指数 - 你不应该盲目地遵循它的所有建议 - 你还需要思考并考虑这些是否是好的建议。

答案 1 :(得分:2)

INCLUDE关键字仅表示包含列的值应存储在索引本身中,以便对于以下查询:

SELECT BazID FROM MyTable WHERE BarFlag = @SomeValue

没有必要对表本身进行额外的查找,以便在执行索引查找后找到BazID的值。