1

尝试通过特定示例了解“覆盖查询的含义”如果我有一个包含 3 列的表:

Col1 Col2 Col3

Col1Col2上放了一个索引

“覆盖查询”是由 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

这三个中哪一个是真正“被覆盖”的?

4

2 回答 2

2

仅涵盖第三个示例。要被覆盖,必须从索引中完全满足查询。您的第一个示例生成的结果完全在索引内,但它需要不属于索引的信息才能完成,因此未涵盖。为了匹配您的第一个示例,您需要一个首先列出 Col3 的索引。

索引的一个重要特性是能够在索引中包含一组列,而无需实际索引这些列。因此,您的表的索引示例可能如下所示:

CREATE INDEX [ix_MyTable] ON [MyTable] 
(
            [Col1] ASC,
            [Col2] ASC
)
INCLUDE ( [Col3]) 

现在样本 2 和 3 都被覆盖了。示例 1 仍未涵盖,因为索引对于 WHERE 子句仍然没有用处。

为什么包括 Col3,而不是与其他列一起列出?重要的是要记住,当您添加索引或使它们变得更复杂时,使用这些索引更改数据的操作将需要越来越多的工作,因为每次更改都需要更新索引。如果您在索引中包含一列,但没有实际索引它,则对该列的更新仍然需要返回并更新索引,以便索引中的数据是准确的......但它也不需要根据新值重新排序索引。所以这为我们的数据库服务器节省了一些工作。换句话说,如果一列只在选择列表中,而不在 where 子句中,您可能会通过包含它在索引中以获得从索引中覆盖查询的好处,而无需在列上实际建立索引。

于 2013-10-01T14:00:23.067 回答
0

它不仅仅是 where 子句和 select 子句。group by 子句还需要其列被索引覆盖才能成为覆盖索引。基本上,要成为覆盖索引,它需要包含给定表的查询中使用的所有列。但是,如果您没有以正确的顺序包含它们,则不会使用索引。

如果索引中的列顺序是 (col1, col2, col3),则索引不能用于查询一,因为您是通过 col3 选择的。可以将其想象为按姓氏排序的电话簿,然后是名字,然后是中间名首字母。查找姓氏为 Smith 的每个人很容易,查找姓氏为 John 的每个人对排序没有帮助,您必须阅读整个电话簿。索引也一样。查找 col1 值很容易。找到一个 col1 值,然后找到 col2 值就可以了。仅查找 col3 或仅 col2 对索引没有帮助。

于 2013-10-01T13:53:52.583 回答