我刚刚在一些数据库讨论中听到术语“覆盖索引” - 它是什么意思?

有帮助吗?

解决方案

A 覆盖指数 是一个索引,其中包含查询所需的所有列(可能还有更多列)。

例如,这个:

SELECT *
FROM tablename
WHERE criteria

通常会使用索引来加速解析要检索的行 标准, ,但随后它将转到完整表来检索行。

但是,如果索引包含列 第 1 列、第 2 列第3栏, ,那么这个sql:

SELECT column1, column2
FROM tablename
WHERE criteria

并且,如果可以使用特定索引来加快要检索的行的解析速度,则该索引已经包含您感兴趣的列的值,因此不必转到表来检索行,但可以直接从索引生成结果。

如果您看到典型的查询使用 1-2 列来解析哪些行,然后通常添加另外 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 检索数据最快的方法之一。

覆盖索引是“覆盖”特定表所需的所有列的索引,从而消除了给定查询/操作访问物理表的需要。

由于索引包含所需的列(或其超集),因此可以用索引查找或扫描来代替表访问,这通常要快得多。

要涵盖的列:

  • 参数化或静态条件;受参数化或常量条件限制的列。
  • 连接列;动态用于连接的列
  • 选定的列;回答选定的值。

虽然覆盖索引通常可以为检索提供良好的好处,但它们确实会增加一些插入/更新开销;由于每次更新时都需要写入额外或更大的索引行。

覆盖连接查询的索引

作为连接查询的性能技术,覆盖索引可能是最有价值的。这是因为连接查询的成本更高,并且比单表检索更有可能遭受高性价比问题。

  • 在连接查询中,应按表考虑覆盖索引。
  • 每个“覆盖索引”都会从计划中删除物理表访问,并将其替换为仅索引访问。
  • 研究计划成本并试验哪些表最值得用覆盖索引替换。
  • 通过这种方式,可以显着降低大型连接计划的乘法成本。

例如:

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.

SELECT Id FROM mytable WHERE Telephone_Number = '55442233';

当您检查此查询的性能时,您会感到失望,因为 Telephone_Number 未建立索引,这需要使用 I/O 调用从表中获取行。因此,这不是覆盖索引,因为查询中有一些列没有索引,这会导致频繁的 I/O 调用。

要使其成为覆盖索引,您需要在其上创建复合索引 (Id, Telephone_Number).

更详细的内容可以参考这个博客:https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top