MySQL覆盖索引优化?

6 浏览
0 Comments

MySQL覆盖索引优化?

刚刚在一些数据库讨论中听到了 "covered index" 这个术语,它是什么意思?

0
0 Comments

Covering index optimization是一个SQL优化方法,它的出现是为了提高查询性能。Covering index是一种普通的索引,如果它能够满足查询的需求而不需要分析数据,就被称为"covering"。

一个例子是在MySQL中创建一个包含ID和Foo两列的表MyTable,并在这两列上创建一个非聚集索引index1。当执行SELECT语句查询ID和Foo列时,由于索引已经覆盖了需要的数据,查询可以直接从索引中获取数据,而不需要访问实际的数据表。这样的查询方式是SQL服务器中最快的方法之一。

然而,有人指出,如果表定义中包含一个主键,主键会创建一个聚集索引在该列上(即ID列),那么将ID列添加到非聚集索引中就是多余的。因为在任何非聚集索引中,聚集键都会被自动添加进去。

对此,另一个人表示这可能是针对特定数据库而言的。他认为大多数数据库会添加一个行位置来标识存储页上的行。主键是一个逻辑标识符,而不是块级别的存储地址。如果前者是正确的,那么就不需要主键索引了,而实际上主键索引是经常需要的。

因此,我们可以得出结论,Covering index optimization的出现是为了提高查询性能,通过创建一个能够满足查询需求的索引,减少对实际数据表的访问。然而,在某些情况下,如果表已经有了聚集索引,将其列再次添加到非聚集索引中可能是多余的。根据具体的数据库实现和需求,选择是否添加主键索引需要谨慎考虑。

0
0 Comments

MySQL覆盖索引优化

覆盖索引是一个包含了查询所需的所有列(可能还包括其他列)的索引。

例如,对于以下SQL查询:

SELECT *
FROM tablename
WHERE criteria

通常会使用索引来加快使用条件进行检索的速度,但最终还是需要到完整的表中检索行。

然而,如果索引包含了列column1、column2和column3,那么对于以下SQL查询:

SELECT column1, column2
FROM tablename
WHERE criteria

只要该特定的索引可以用于加快检索行的速度,索引已经包含了你所感兴趣的列的值,因此不需要到表中检索行,而是可以直接从索引中产生结果。

如果你发现一个典型的查询只使用1-2列来解析行,然后通常添加另外1-2列,如果这些额外的列(如果它们在所有地方都相同)追加到索引中,那么查询处理器可以从索引本身获取所有需要的内容。

关于这个主题的文章:Index Covering Boosts SQL Server Query Performance

这是一个关于覆盖索引的深入解释:cubrid.org/cubrid_covering_index。这篇文章通过图表和真实的SQL示例提供了解释。还解释了覆盖索引如何提高数据库性能。

那么,如果我为col1、col2和col3创建一个覆盖索引,那么我知道使用col1、2和3的查询将很快,但如果我还有一个只使用col2和col3的查询呢?它会使用覆盖索引还是进行完整的表扫描?我应该为col2和col3的组合创建一个单独的覆盖索引吗?

关于覆盖索引,我找到的最好的文章是:red-gate.com/simple-talk/sql/learn-sql-server/...

这篇文章使用简单的术语进行了解释:orangematter.solarwinds.com/2019/02/01/...

0
0 Comments

MySQL covering index optimization是一个关于优化MySQL查询性能的问题。出现这个问题的原因是因为在查询中使用了覆盖索引,它可以减少访问物理表的次数,从而提高查询的速度。覆盖索引包含了查询所需的所有列,因此可以用索引查找或扫描来替代访问物理表。

覆盖索引的使用方法如下:

- 参数化或静态条件:对受参数化或常量条件限制的列使用覆盖索引。

- 连接列:对用于连接的动态列使用覆盖索引。

- 选定列:用于返回选定值的列。

虽然覆盖索引在检索方面通常可以提供良好的性能优势,但它们也会增加插入/更新的开销,因为每次更新都需要写入额外或更大的索引行。

覆盖索引在连接查询中的应用最为重要。这是因为连接查询比单表检索更昂贵,更容易出现性能问题。在连接查询中,应该根据每个表来考虑使用覆盖索引。每个覆盖索引都可以替换一个物理表的访问,并用索引的方式来访问。可以通过调查计划成本并尝试替换哪些表最值得使用覆盖索引来显著减少大型连接查询计划的成本。

以下是一个示例:

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);

可以参考以下链接了解更多信息:http://literatejava.com/sql/covering-indexes-query-optimization/

0