什么是MySQL的回表?

因为我们日常开发中用的最多的存储引擎,目前就是InnoDB这个存储引擎了,所以今天主要是探讨一下InnoDB存储引擎中的索引。从物理存储的角度来对索引进行分类,可以分为聚簇索引和二级索引。

下面我们直接来看一下例子:

mysql 复制代码
create table user_info
(
    id      bigint auto_increment comment '主键'
        primary key,
    age     int                     null comment '年龄',
    name    varchar(50)  default '' null comment '姓名',
    address varchar(200) default '' null comment '住址'
)
    comment '用户信息';

create index idx_name
    on user_info (name);

我们建了一张用户信息表,包含id主键、age、name、address四个字段,指定该表所使用的存储引擎为InnoDB,插入了8条数据以供测试。在这个例子中,user_info表的聚簇索引是建立在id字段上的,我们把主键id插入b+tree得到下图:

由此,我们可以画出id索引树:

从图中可以看出,聚簇索引的每个叶子节点存储了一行完整的表数据,叶子节点间用双向链表按照id列递增连接起来,可以很方便的进行顺序检索。

InnoDB表是要求必须有聚簇索引的,默认是在主键字段上建立。如果你的表没有主键,那么默认表的第一个not null的唯一索引将被建立为聚簇索引,在前两者都没有的情况下,InnoDB将自动生成一个隐式自增id列并在此列上创建聚簇索引。

然后我们再来看看二级索引,我们是在表中的name字段上加了二级索引idx_name。

由此,我们可以画出idx_name索引树:

从图中我们可以看出二级索引的叶子节点并不是存储一行完整的表数据,而是存储了索引字段的值和聚簇索引所在列的值,也就是id列的值。

由于二级索引的叶子节点不存储完整的表数据,所以如果你的查询sql有索引字段以外的字段,那么就需要回到聚簇索引中去进一步获取数据。

举个例子:

mysql 复制代码
select * from user_info where name = '王五';

在二级索引idx_name中查询到主键id=3,接着带着id=3这个条件,回到聚簇索引查询剩下的age和address字段,很明显,回表操作需要额外的B+tree搜索过程,会增加查询耗时。当然了,回表这个过程不是必须的,当查询的字段在二级索引中都能找到时,就不需要回表,MySQL称此时的二级索引为覆盖索引或称触发了索引覆盖。

举个例子:

mysql 复制代码
select id,name from user_info where name = '王五';

这条sql只查询了id字段和name字段,二级索引中已经包含了需要查询的所有字段,所以就不用回表了。

相关推荐
液态不合群4 小时前
[特殊字符] MySQL 覆盖索引详解
数据库·mysql
计算机毕设VX:Fegn08955 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
没差c6 小时前
springboot集成flyway
java·spring boot·后端
三水不滴6 小时前
Redis 过期删除与内存淘汰机制
数据库·经验分享·redis·笔记·后端·缓存
笨蛋不要掉眼泪6 小时前
Spring Boot集成LangChain4j:与大模型对话的极速入门
java·人工智能·后端·spring·langchain
sheji34169 小时前
【开题答辩全过程】以 基于SpringBoot的疗养院管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
盒马coding9 小时前
深度解密MySQL2PG工具MySQL至PostgreSQL语法全景拆解过程
数据库·mysql·postgresql
Nandeska9 小时前
13、MySQL半同步复制示例
数据库·mysql
短剑重铸之日9 小时前
《设计模式》第六篇:装饰器模式
java·后端·设计模式·装饰器模式
液态不合群9 小时前
【面试题】MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别?
android·数据库·mysql