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",说明使用了覆盖索引

相关推荐
阿维的博客日记3 分钟前
Redis的旁路缓存策略和先删除缓存后更新数据库,先更新数据库后删除缓存,这三种策略之间有什么关系??
数据库·redis·缓存
ictI CABL19 分钟前
redis连接服务
数据库·redis·bootstrap
逻辑驱动的ken25 分钟前
Java高频面试考点场景题21
java·开发语言·面试·职场和发展·求职招聘
苍煜27 分钟前
SpringBoot单体应用到分布式下的数据库锁、事务、Redis事务、分布式锁、分布式事务协调
数据库·spring boot·分布式
xmjd msup1 小时前
mysql的分区表
数据库·mysql
Lyyaoo.1 小时前
【JAVA Spring面经】Spring 事务失效情况
java·数据库·spring
MeAT ITEM1 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dovens1 小时前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.11 小时前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
辛苦才能1 小时前
数据结构--排序--插入排序(C语言,重点排序面试和比赛都会考察)
c语言·数据结构·面试