查看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
关键字吗?
答案 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
的值。