Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 什么是覆盖指数?_Sql_Database_Indexing - Fatal编程技术网

Sql 什么是覆盖指数?

Sql 什么是覆盖指数?,sql,database,indexing,Sql,Database,Indexing,我刚刚在一些数据库讨论中听到了covered index一词,它是什么意思?covered index是一个包含查询所需的所有列,甚至更多列的索引 例如: SELECT * FROM tablename WHERE criteria 通常将使用索引来加快使用条件检索哪些行的解析速度,但随后将转到完整表来检索这些行 但是,如果索引包含列1、列2和列3,则此sql: SELECT column1, column2 FROM tablename WHERE criteria 而且,如果可以使用特定

我刚刚在一些数据库讨论中听到了covered index一词,它是什么意思?

covered index是一个包含查询所需的所有列,甚至更多列的索引

例如:

SELECT *
FROM tablename
WHERE criteria
通常将使用索引来加快使用条件检索哪些行的解析速度,但随后将转到完整表来检索这些行

但是,如果索引包含列1、列2和列3,则此sql:

SELECT column1, column2
FROM tablename
WHERE criteria
而且,如果可以使用特定的索引来加快要检索的行的解析速度,则该索引已经包含您感兴趣的列的值,因此它不必转到表来检索行,而是可以直接从索引生成结果

如果您看到一个典型的查询使用1-2列来解析哪些行,然后通常会添加另外1-2列,那么将这些额外的列(如果它们全部相同)附加到索引中可能会很有用,这样查询处理器就可以从索引本身获取所有信息


这里有一个关于这个主题的例子。

覆盖索引只是一个普通索引。如果它能够满足查询而无需分析数据,则称为“覆盖”

例如:

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';
当您检查此查询的性能时,您将被拒绝,因为
电话号码
没有索引,所以需要使用I/O调用从表中提取行。所以,这不是一个覆盖索引,因为查询中有一些列没有索引,这导致频繁的I/O调用

要使其成为覆盖索引,您需要在
(Id,电话号码)
上创建一个复合索引

有关更多详细信息,请参阅本博客:

下面是关于什么是覆盖指数的一个非常深入的解释。本文使用图形和真实的SQL示例提供了解释。还解释了覆盖索引如何提高数据库性能。因此,如果我将col1、col2和col3的覆盖索引创建为一个索引,那么我知道使用col1、col2和col3的查询会很快,但是如果我还有一个只使用col2和col3的查询呢?它会使用覆盖索引还是进行全表扫描?我应该为col2和col3的组合创建一个单独的覆盖索引吗?我在覆盖索引中找到的最好的文章是:吹毛求疵,但由于表定义包含一个主键,它会在该列(ID)上创建聚集索引,因此将ID列添加到非聚集索引是多余的。聚集键会自动添加到任何非聚集索引中。@edosoft--您的注释可能是特定于数据库的。我的理解是,大多数数据库都会在存储页面上添加一个行位置来寻址该行。主键是逻辑标识符,而不是块级存储地址。如果您的主张是正确的,那么就不需要主键索引——这实际上是经常需要的。