阿里二面:什么是 MySQL 回表查询?如何避免?(修订版)
在线 Java 面试刷题持续更新https://www.quanxiaoha.com/java-interview目录面试考察点核心答案深度解析一、InnoDB 索引结构理解回表的前提二、回表过程演示三、如何避免回表—— 覆盖索引四、如何判断是否发生回表五、覆盖索引的最佳实践面试高频追问常见面试变体记忆口诀总结面试考察点索引原理理解面试官不仅仅是想知道 回表 这个概念更是想考察你是否理解 InnoDB 的聚簇索引和二级索引的区别以及 B 树的存储结构。性能优化意识回表会带来额外的 I/O 开销考察你是否具备 减少回表次数 的优化思维能否在实际开发中设计出高效的索引。覆盖索引应用考察你是否掌握 覆盖索引 这一核心优化手段以及如何通过EXPLAIN命令判断是否发生了回表。核心答案回表查询当通过二级索引非主键索引查询数据时如果 SELECT 的字段不完全包含在索引中MySQL 需要先从二级索引树查到主键 ID再回到聚簇索引树根据 ID 查找完整记录这个过程叫 回表。核心对比查询类型索引类型是否回表性能主键查询聚簇索引❌ 不需要⭐⭐⭐⭐⭐ 最快覆盖索引查询二级索引字段全覆盖❌ 不需要⭐⭐⭐⭐ 快普通二级索引查询二级索引字段未覆盖✅ 需要回表⭐⭐⭐ 较慢一句话总结回表的本质是 二级索引 → 聚簇索引 的二次查找通过覆盖索引可以避免。深度解析一、InnoDB 索引结构理解回表的前提要理解回表首先要理解 InnoDB 的两种索引结构聚簇索引和二级索引结构对比上图对比了聚簇索引和二级索引的结构差异。关键区别在于聚簇索引主键索引叶子节点存储的是完整的行数据通过主键可以直接获取所有字段二级索引非主键索引叶子节点只存储索引列的值 主键 ID不包含其他字段这就是为什么二级索引查询可能需要 回表 —— 因为它没有完整的行数据 欢迎加入小哈的星球你将获得:专属的项目实战多个项目 / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论新项目《Spring AI 项目实战》正在更新中..., 基于 Spring AI Spring Boot 3.x JDK 21;《从零手撸仿小红书微服务架构》 已完结基于 Spring Cloud Alibaba Spring Boot 3.x JDK 17..., 点击查看项目介绍演示地址http://116.62.199.48:7070/《从零手撸前后端分离博客项目全栈开发》2期已完结,演示链接http://116.62.199.48/;专栏阅读地址https://www.quanxiaoha.com/column截止目前累计输出 100w 字讲解图 4013 张还在持续爆肝中..后续还会上新更多项目目标是将 Java 领域典型的项目都整一波如秒杀系统, 在线商城, IM 即时通讯Spring Cloud Alibaba 等等戳我加入学习解锁全部项目已有4500小伙伴加入二、回表过程演示假设有一张用户表CREATE TABLE user ( id INT PRIMARY KEY, -- 主键 name VARCHAR(50), -- 姓名 age INT, -- 年龄 INDEX idx_name (name) -- name 列的二级索引 ); -- 插入测试数据 INSERT INTO user VALUES (1, Alice, 25); INSERT INTO user VALUES (2, Bob, 30); INSERT INTO user VALUES (3, Carol, 28);场景通过 name 查询完整数据SELECT * FROM user WHERE name Bob;这个查询会发生回表执行过程如下回表过程演示上图展示了回表的完整过程。核心步骤说明步骤一在二级索引idx_name中查找name Bob找到对应的主键id 3步骤二拿着主键id 3回到聚簇索引树中查找完整的行数据回表代价需要扫描两棵 B 树产生额外的 I/O 开销三、如何避免回表—— 覆盖索引覆盖索引Covering Index如果查询的所有字段都包含在索引中MySQL 就不需要回表直接从索引树获取数据即可。优化前会回表-- 查询 name 和 age但 idx_name 索引只有 name没有 age -- 所以需要回表获取 age 字段 SELECT name, age FROM user WHERE name Bob;优化后不回表-- 创建联合索引包含 name 和 age CREATE INDEX idx_name_age ON user(name, age); -- 再次查询name 和 age 都在索引中不需要回表 SELECT name, age FROM user WHERE name Bob;回表查询和覆盖索引对比上图对比了回表查询和覆盖索引的执行差异。覆盖索引的核心优势减少 I/O只扫描一棵 B 树避免回表的额外 I/O提升性能特别是高并发场景减少 I/O 意味着更高的 QPS索引下推MySQL 5.6 之后覆盖索引还能配合 ICP 进一步优化四、如何判断是否发生回表使用EXPLAIN命令查看执行计划关注Extra字段-- 会回表的查询 EXPLAIN SELECT * FROM user WHERE name Bob;字段值含义typeref使用了二级索引keyidx_name使用的索引名ExtraNULL❌ 没有使用覆盖索引需要回表-- 覆盖索引查询不回表 EXPLAIN SELECT name, age FROM user WHERE name Bob;字段值含义typeref使用了二级索引keyidx_name_age使用的联合索引ExtraUsing index✅ 使用了覆盖索引不回表关键指标Extra字段出现Using index表示使用了覆盖索引不会回表。五、覆盖索引的最佳实践1. 高频查询字段建联合索引-- 业务高频查询SELECT name, age FROM user WHERE name ? CREATE INDEX idx_name_age ON user(name, age);2. 遵循最左前缀原则-- 联合索引 (name, age, phone) CREATE INDEX idx_name_age_phone ON user(name, age, phone); -- ✅ 走覆盖索引 SELECT name, age FROM user WHERE name Bob; -- 用到 name SELECT name, age, phone FROM user WHERE name Bob; -- 用到 name, age, phone SELECT name, age FROM user WHERE name Bob AND age 30; -- 用到 name, age -- ❌ 不走覆盖索引违反最左前缀 SELECT name, age FROM user WHERE age 30; -- 没有 name 条件3. 避免 SELECT *-- ❌ 可能导致回表 SELECT * FROM user WHERE name Bob; -- ✅ 只查需要的字段利用覆盖索引 SELECT name, age FROM user WHERE name Bob;面试高频追问追问一主键查询和二级索引查询有什么区别答主键查询直接走聚簇索引叶子节点存完整数据不需要回表二级索引查询如果字段不覆盖需要先查主键 ID 再回表查完整数据。追问二为什么不建议用SELECT *答SELECT *会查询所有字段如果走二级索引大概率字段不全覆盖必须回表而明确指定字段可以设计覆盖索引避免回表提升性能。追问三联合索引的设计原则是什么答遵循 最左前缀原则将高频查询条件放左边覆盖查询字段放右边同时考虑区分度区分度高的字段放前面。常见面试变体什么是覆盖索引它有什么优势为什么主键查询比二级索引查询快如何优化 SQL 减少 I/O 次数EXPLAIN 的 Extra 字段中 Using index 是什么意思记忆口诀回表与覆盖索引二级索引存 ID叶子节点不存完整数据回表查聚簇拿着 ID 再查一次覆盖免回表查询字段全在索引中总结回表是 InnoDB 通过二级索引查询时因索引不包含完整数据而需要二次查找聚簇索引的过程。避免回表的核心手段是覆盖索引—— 将查询涉及的字段都放入联合索引使 MySQL 能直接从索引树获取所有数据。生产环境中应避免SELECT *根据高频查询设计合理的联合索引。 欢迎加入小哈的星球你将获得:专属的项目实战多个项目 / 1v1 提问 /Java 学习路线 /学习打卡 / 每月赠书 / 社群讨论新项目《Spring AI 项目实战》正在更新中..., 基于 Spring AI Spring Boot 3.x JDK 21;《从零手撸仿小红书微服务架构》 已完结基于 Spring Cloud Alibaba Spring Boot 3.x JDK 17..., 点击查看项目介绍演示地址http://116.62.199.48:7070/《从零手撸前后端分离博客项目全栈开发》2期已完结,演示链接http://116.62.199.48/;专栏阅读地址https://www.quanxiaoha.com/column截止目前累计输出 100w 字讲解图 4013 张还在持续爆肝中..后续还会上新更多项目目标是将 Java 领域典型的项目都整一波如秒杀系统, 在线商城, IM 即时通讯Spring Cloud Alibaba 等等戳我加入学习解锁全部项目已有4500小伙伴加入1. 我的私密学习小圈子从0到1手撸企业实战项目~ 2. 如何画出一张优秀的架构图老鸟必备 3. 面试官说说动态线程池实现原理 4. 实战Arthas 定位 接口的超时问题直接起飞最近面试BAT整理一份面试资料《Java面试BATJ通关手册》覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。 获取方式点“在看”关注公众号并回复 Java 领取更多内容陆续奉上。PS因公众号平台更改了推送规则如果不想错过内容记得读完点一下“在看”加个“星标”这样每次新文章推送才会第一时间出现在你的订阅列表里。 点“在看”支持小哈呀谢谢啦
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2439932.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!