高性能的MySQL(5)索引策略-覆盖索引与索引排序

本文深入探讨了MySQL中覆盖索引的概念、优势及使用场景,详细解释了覆盖索引如何优化查询效率,包括索引扫描排序、InnoDB与MyISAM引擎差异、覆盖索引与查询性能的关系,并提供了实例分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、覆盖索引

索引是一种查找数据的高效方式,但是MySQL也可以使用索引来直接获取列的数据,这样就不再需要读取数据行。如果索引的叶子节点中已经包含要查询的数据,那么还有什么必要回表查询呢?

如果一个索引包含或者说覆盖所有需要查询的字段的值,我们就称之为“覆盖索引”。

覆盖索引的好处:

1、索引条目通常远小于数据行大小,所以如果只需要读取索引,就极大的减少数据访问量。这对MyISAM尤其正确,因为MyISAM能压缩索引以变得更小。

2、因为索引是按照顺序存储的,所以对于I/O密集型的范围查询会比随机从磁盘读取每一行数据的I/O要少很多。

3、由于InnoDB的聚簇索引,覆盖索引对InnoDB特别有用。InnoDB的二级索引在叶子节点中保存了行的主键值,所以如果二级主键能够覆盖查询,则可以避免对主键索引的二次查询。


覆盖索引必须要存储索引列的值,而哈希索引、空间索引、和全文索引都不能存储列的值,所以MySQL只能使用B-Tree索引做覆盖索引


当发起一个索引覆盖的查询时,在EXPLAIN的Extra列可以看到Usingindex的信息。例如:

115243971.png


如果索引覆盖了WHERE条件中的字段,但不是整个查询涉及的字段,看看是什么情况

120323463.png

没有任何索引能覆盖这个查询,因为查询从表中选择了所有的列,而没有任何索引覆盖所有的列。但是索引还是用到了。


接下来可以对比一下,可以使用聚簇索引的InnoDB和MyISAM对覆盖索引的区别。

首先看MyISAM表,表结构如下

122724869.png

看一下如下这个查询,没有用到覆盖索引

122849961.png


对同样结构的InnoDB引擎,来看下会有什么不同的结果。

123034119.png

同样的查询,只是表引擎不一样,看看结果

123128899.png

这是因为InnoDB的二级索引的叶子节点包含了主键的值,这意味着InnoDB的二级索引可以有效的利用这些额外的主键来覆盖查询。

由于InnoDB的聚簇索引,虽然查询条件的索引列并不包含主键,但是也能够做到对主键做覆盖查询。


二、使用索引扫描来排序

MySQL有两种方式可以生成有序结果。

1、通过排序操作

2、按索引顺序扫描

如果EXPLAIN出来的type列的值为“index”,则说明使用了索引扫描排序。

MySQL可以使用同一个索引既满足排序,有用于查找行,设计索引时应该进可能的满足这两种任务才是最好的。

只有当索引的顺序和ORDERBY的顺序完全一致,并且所有列的排序方向都一样时,才能使用索引来对结果进行排序。如果是关联多个张表,则只有ORDERBY子句引用的字段全部是第一个表时,才能使用索引排序。同时ORDERBY也需要满足最左前缀的要求。

有一种情况下ORDERBY可以不满足最左前缀要求,那就是前导列为常量的时候,接下来我们用例子来看看。

135201217.png

虽然ORDERBY子句不满足最左前缀,但是依然可以索引排序,这是因为索引的第一列被指定为一个常数。

如果不是常数,不会使用索引排序

135954642.png

下面这也可以使用索引排序

135447433.png

135839559.png

不能使用索引排序的查询

1、查询使用了不同的排序方向,索引列都是正序定义的

140701505.png

2、排序字段不在索引列

140856286.png

3、无法组成最左前缀

140952786.png

4、某个列有范围查询

141246961.png

DONE!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值