什么是涵盖索引?

我刚刚在一些数据库讨论中听到了涵盖索引的术语 – 这是什么意思?

覆盖索引是包含查询所需的所有列和可能更多列的索引。

比如这个:

SELECT * FROM tablename WHERE criteria 

通常会使用索引来加速使用条件检索哪些行的解决scheme,但是随后它将转到整个表以检索行。

但是,如果索引包含列column1,column2column3 ,那么这个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/