MySQL中的回表是什么?

回表是指在使用 非聚簇索引(二级索引)**进行查询时,若索引中未包含查询所需的全部数据,需要根据索引中的主键值回到聚簇索引(主键索引)**中查找完整数据行的过程。这一操作会增加额外的磁盘 I/O,可能对查询性能产生影响。

举一个例子。比如用户表,id是主键,name有索引。当执行SELECT * FROM users WHERE name='Arm'时,先通过name索引找到对应的id,再用id去主键索引里查整行数据。这时候就发生了两次索引查找,即回表。

select * from user where age = 20;需要根据二级索引(age)找到age = 20的主键键值,然后需要再根据主键去找整行的数据。主键索引频繁查询可能会造成大量随机I/O:

在磁盘上,数据是以数据页为单位进行存储和读取的。如果 age 为 20 的人很多,并且这些记录对应的主键 id 是无序且不连续的,那么在回表过程中,根据这些主键 id 到主键索引中查找记录时,就会需要频繁地访问不同的数据页。例如,一个 age 为 20 的记录对应的主键 id 是 10,下一个 age 为 20 的记录对应的主键 id 可能是 100,这两个 id 对应的记录很可能存储在不同的数据页上。磁盘在读取数据时,磁头需要移动到相应的位置才能读取数据。当需要频繁地访问不同的数据页时,磁头就需要不断地移动,这会带来大量的寻道时间和旋转延迟,也就是随机 I/O。与顺序 I/O 相比,随机 I/O 的性能要差很多,因为顺序 I/O 可以在一次磁头移动过程中连续读取多个数据页,而随机 I/O 每次都需要重新定位磁头,大大增加了磁盘 I/O 的开销。

举例:

假设 user 表中有如下部分数据:

id age
1 20
5 20
15 20
25 20

age 索引中可以快速找到 age 为 20 的记录对应的主键值 151525。但这些主键值在主键索引中对应的记录可能分散在不同的数据页上,例如 id 为 1 的记录在数据页 A,id 为 5 的记录在数据页 B,id 为 15 的记录在数据页 C,id 为 25 的记录在数据页 D。那么在回表时,就需要依次从数据页 A、B、C、D 中读取数据,这就导致了大量的随机 I/O。

所以当 age 为 20 的人很多且主键 id 无序不连续时,回表过程中主键索引的频繁查询会造成大量随机 I/O,从而影响查询性能。

如何避免回表:

可以使用覆盖索引

覆盖索引指索引包含查询所需的所有字段,无需回表即可返回结果:

sql 复制代码
 -- 查询只需 name 和 age,建立联合索引 (name, age)
 CREATE INDEX idx_name_age ON users(name, age);
 ​
 -- 执行以下查询时,无需回表
 SELECT name, age FROM users WHERE name = '张三';

避免使用 SELECT *,只选择必要的字段:

sql 复制代码
 -- 避免回表
 SELECT id, name FROM users WHERE name = '张三';
 ​
 -- 需要回表(除非索引覆盖所有字段)
 SELECT * FROM users WHERE name = '张三';

如何判断是否发生了回表

可以通过EXPLAIN命令查看执行计划,如果Extra列显示"Using index",说明使用了覆盖索引

相关推荐
小陈phd几秒前
Text2SQL智能体学习笔记(二)——NL2SQL落地的隐形基石:元数据库
数据库·笔记·学习
霸道流氓气质2 分钟前
阿里云 OSS 从零到实战:概念、配置与 Spring Boot 集成指南
数据库·spring boot·阿里云
茉莉玫瑰花茶2 分钟前
综合案例 - AI 智能租房助手 [ 4 ]
数据库·python·ai·langgraph
浮午3 分钟前
腾讯AI应用开发一面实录:13道硬核面试题全解析
人工智能·面试·职场和发展
ULIi096kr4 分钟前
MySQL查看表创建时间、修改时间、最后更新时间(精准排查僵尸表)
数据库·mysql
折哥的程序人生 · 物流技术专研17 分钟前
Tomcat 严重警告:JDBC 驱动未注销 + 工作线程泄漏 —— 原因、影响与彻底修复(生产级终极指南)
java·运维·数据库·mysql·oracle·tomcat
初圣魔门首席弟子23 分钟前
Qt C++ 项目实战:修改共享头文件后的高效增量编译与快速发布流程
数据库
wb0430720123 分钟前
仓库搬家不停业——从阿明的“在线换仓库“,看数据库迁移与 Schema 演进的实战方法论
数据库·adb·架构
lx1885486989627 分钟前
Redis大Key阻塞:单线程CPU100%的致命陷阱
数据库·redis·缓存
IT策士31 分钟前
Redis 从入门到精通:位图、HyperLogLog、GEO
数据库·redis·缓存