什么是涵盖索引?
我刚刚在一些数据库讨论中听到了涵盖索引的术语 – 这是什么意思?
覆盖索引是包含查询所需的所有列和可能更多列的索引。
比如这个:
SELECT * FROM tablename WHERE criteria
通常会使用索引来加速使用条件检索哪些行的解决scheme,但是随后它将转到整个表以检索行。
但是,如果索引包含列column1,column2和column3 ,那么这个sql:
SELECT column1, column2 FROM tablename WHERE criteria
并且,如果可以使用特定的索引来加速要检索的行的parsing,那么索引已经包含了您感兴趣的列的值,所以它不必去表中检索行,但是可以直接从索引产生结果。
如果您看到典型的查询使用1-2列来parsing哪些行,然后通常会添加另外的1-2列,那么也可以使用这种方法,那么追加那些额外的列(如果它们全部相同)添加到索引,以便查询处理器可以从索引本身获取所有内容。
以下是一篇文章:索引覆盖提高SQL Server查询性能的主题。
覆盖指数只是一个普通的指标。 如果能够满足查询而不需要分析数据,则称之为“覆盖”。
例:
CREATE TABLE MyTable ( ID INT IDENTITY PRIMARY KEY, Foo INT ) CREATE NONCLUSTERED INDEX index1 ON MyTable(ID, Foo) SELECT ID, Foo FROM MyTable -- All requested data are covered by index
这是从SQL Server中检索数据的最快方法之一。
覆盖索引是“覆盖”来自特定表的所有列的索引,对于给定的查询/操作完全不需要访问物理表。
由于索引包含所需的列(或者它们的超集),因此可以用索引查找或扫描replace表访问 – 这通常要快得多。
包括的专栏:
- 参数化或静态条件; 列受限于参数化或常量条件。
- join栏目; dynamic用于连接的列
- 选定的栏目; 回答选定的值。
虽然覆盖索引通常可以为检索提供很好的好处,但它们的确增加了插入/更新开销; 由于需要在每次更新时写入更多或更大的索引行。
涵盖联合查询的索引
覆盖索引可能作为连接查询的性能技术最有价值。 这是因为join的查询成本更高,更有可能单表检索遭受高成本性能问题。
- 在join的查询中,应该按照每个表来考虑覆盖索引。
- 每个“覆盖索引”从计划中删除一个物理表访问,并用仅索引访问replace它。
- 调查计划成本和实验哪些表是最值得用覆盖指数代替。
- 通过这种方式,可以显着减less大型连接计划的乘法成本。
例如:
select oi.title, c.name, c.address from porderitem poi join porder po on po.id = poi.fk_order join customer c on c.id = po.fk_customer where po.orderdate > ? and po.status = 'SHIPPING'; create index porder_custitem on porder (orderdate, id, status, fk_customer);
看到:
比方说,你有一个简单的表,下面的列,你只有在这里索引ID:
Id (Int), Telephone_Number (Int), Name (VARCHAR), Address (VARCHAR)
想象一下,你必须运行下面的查询,并检查是否使用索引,以及是否有效地执行没有I / O调用。 请记住,您只在Id
上创build了一个索引。
SELECT Id FROM mytable WHERE Telephone_Number = '55442233';
当你检查这个查询的性能时,你会感到失望,因为Telephone_Number
没有索引,所以需要使用I / O调用从表中获取行。 所以,这不是一个索引覆盖,因为查询中有一些列没有索引,导致频繁的I / O调用。
要使其成为覆盖索引,您需要在(Id, Telephone_Number)
上创build一个复合索引。
有关更多详情,请参阅此博客: https : //www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/