尝试通过特定示例了解“涵盖查询的含义” 如果我有一个表3列的表:
Col1 Col2 Col3
我在 Col1 和 Col2
上添加了索引是“覆盖查询”由SELECT中选择的列或WHERE子句中的列确定? 因此:
1) select Col1, Col2 from MyTable where Col3=XXX
2) Select Col3 from MyTable where Col1=xxx and Col2=yyy
3) Select Col1, Col2 from MyTable where Col1=xxx and Col2=yyy
这三者中哪一个真正“涵盖”?
答案 0 :(得分:2)
仅涵盖第三个示例。要覆盖,必须从索引中完全满足查询。您的第一个示例生成的结果完全在索引中,但它需要的信息不是索引的一部分才能完成,因此不包括在内。要匹配您的第一个示例,您需要一个列出Col3 first 的索引。
索引的一个重要特性是能够在索引中包含一组列而无需实际索引这些列。因此,您的表的索引示例可能如下所示:
CREATE INDEX [ix_MyTable] ON [MyTable]
(
[Col1] ASC,
[Col2] ASC
)
INCLUDE ( [Col3])
现在样本2和3都被覆盖了。样本1仍然没有被覆盖,因为索引对WHERE子句仍然没用。
为什么包含Col3,而不仅仅是将其与其他人一起列出?重要的是要记住,当您添加索引或使其更复杂时,使用这些索引更改数据的操作将需要越来越多的工作,因为每次更改还需要更新索引。如果在索引中包含列而不实际索引它,那么对该列的更新仍需要返回并更新索引,以便索引中的数据准确... 但它不会t还需要根据新值重新排序索引。这样可以节省我们数据库服务器的一些工作。换句话说,如果列只在选择列表中,而不在where子句中,那么包括在索引中可以获得一个小的性能优势,以获得覆盖的好处来自索引的查询,而不实际对列进行索引。
答案 1 :(得分:0)
不仅仅是where子句和select子句。 group by子句还需要索引覆盖其列,以使其成为覆盖索引。基本上,要成为覆盖索引,它需要包含查询中使用的给定表的所有列。但是,如果您没有按正确的顺序包含它们,则不会使用索引。
如果索引中的列顺序是(col1,col2,col3),则索引不能用于查询,因为您是通过col3选择的。可以把它想象成一个按姓氏排序的电话簿,然后是名字,然后是中间的首字母。找到名字史密斯的每个人都很容易,找到名字约翰的每个人都没有帮助排序,你必须阅读整本电话簿。索引相同。找到col1值很容易。找到col1值然后找到col2值就可以了。索引没有帮助找到col3或者只是col2。