一分钟带你学会MySQL覆盖索引,让你的SQL更高效

数据库 MySQL
在我们查询SQL时,我们不仅要考虑where条件是否匹配了索引,还要尽量考虑查询的字段是否可以通过索引直接获取,覆盖索引可以减少树的搜索次数,显著的提升SQL查询性能。

覆盖索引是MySQL优化sql性能的一种非常重要而且常用的手段,通过覆盖索引,我们可以直接查询到需要的结果,而不用回表,从而大大减少树的搜索次数,非常明显的提升查询性能。

数据如何存储与查找

我们知道,MySQL的数据都是存储在B+树上的,每一个索引都代表一个B+树。

对于主键索引,叶子节点存储的是一行记录的所有字段值(逻辑上),而非主键索引的叶子节点存储的是主键值,非叶子节点存储的是索引以及指向数据的指针。

那我们查询数据的时候,MySQL是如何执行的呢?

以主键索引为例,就是在主键索引树上,从根节点出发,一直向下查找,直到找到符合条件的记录。

如果我们要查下图中的User2节点,那么查找路径就是UserA->UserC->UserF->User2。

回表

只按照主键查询是一种理想中的状态,随着业务逐渐复杂,表中的字段会越来越多,我们也会建立更多的非主键索引以应对业务带来的挑战。

但是非主键索引会带来一个问题:回表。

以下面这条sql为例:

select * from t where m in (3,4);

我们在表t的m字段上设置一个索引,那么这条sql的执行流程就是:

  1. 在索引树m上,找到记录3,获取到主键id,比如id=100;
  2. 拿着100这个id去主键索引树上,获取到这一行的数据;
  3. 在索引树m上,找到记录4,获取到主键id,比如id=101;
  4. 拿着101这个id去主键索引树上,获取到这一行的数据;
  5. 在索引树上查找下一个记录5(不一定是5,这里的5只是代表记录4后面的一条记录),记录5不符合查询条件,结束查询。

在上面的流程中,步骤2,4代表了回主键索引树搜索,这个动作就叫做回表。

而MySQL之所以做回表这个动作,是因为我们要查的数据 select *,只有在主键索引树上才有,所以不得不回表查询。

覆盖索引

如果我们把上面的sql改成下面这样:

select id from t where m in (3,4);

这个时候只需要查询id就行,而id这个值已经在m索引树上了,这时就不用再回表了,可以直接提供查询结果。

可以说,索引m覆盖了我们的查询请求,这种情况我们就称为覆盖索引。

这也是为什么我们在很多MySQL规范中可以看到,要求我们查询数据时尽量避免"select *",就是因为"select *"会导致覆盖索引失效,从而引起强制回表,sql性能可能大幅下降。

最后

在我们查询SQL时,我们不仅要考虑where条件是否匹配了索引,还要尽量考虑查询的字段是否可以通过索引直接获取,覆盖索引可以减少树的搜索次数,显著的提升SQL查询性能。

责任编辑:姜华 来源: 今日头条
相关推荐

2015-11-12 10:32:40

GitHub控制系统分布式

2017-07-06 08:12:02

索引查询SQL

2016-09-12 17:28:45

云存储应用软件存储设备

2017-03-30 19:28:26

HBase分布式数据

2019-02-28 15:04:36

显卡兼容芯片

2022-06-02 08:46:04

网卡网络服务器

2017-02-21 13:00:27

LoadAverage负载Load

2018-07-31 16:10:51

Redo Undo数据库数据

2018-06-26 05:23:19

线程安全函数代码

2020-05-21 19:46:19

区块链数字货币比特币

2022-07-18 06:16:07

单点登录系统

2011-02-21 17:48:35

vsFTPd

2018-08-17 07:19:34

网络故障硬件软件

2020-07-09 07:37:06

数据库Redis工具

2020-07-17 07:44:25

云计算边缘计算IT

2018-12-12 22:51:24

Java包装语言

2021-09-28 14:02:19

电脑主板黑屏

2023-03-10 13:29:00

MySQLCount函数

2016-12-16 11:05:00

分布式互斥线程

2018-03-27 09:28:33

缓存策略系统
点赞
收藏

51CTO技术栈公众号