ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MySQL面试50问:索引调优与慢SQL优化核心指南

MySQL面试50问:索引调优与慢SQL优化核心指南 最近在梳理 MySQL 面试题时发现很多同学面对索引优化相关问题要么只会背八股文要么遇到线上慢 SQL 就不知道从哪下手。尤其是 2026 年的面试趋势单纯问“什么是索引”已经越来越少更多是结合执行计划、索引失效、MVCC、锁机制来考你真实调优能力。这篇文章把 MySQL 面试中最常出现的 50 个问题整理成一条完整学习线重点拆解索引调优、事务隔离、慢 SQL 定位等核心考点。不管你是准备校招、社招还是想在项目里真正优化数据库性能都可以直接对照本文查漏补缺。1. MySQL面试题到底在考什么MySQL 相关的面试题在技术面试中占比一直很高尤其是后端开发岗位。很多同学以为背熟索引分类、事务四大特性就足够但到了现场面试面试官往往会追问到底层实现、失效场景、执行计划分析。所以弄清面试官真正考察的能力模型比盲目刷题更重要。1.1 面试中的考察层次MySQL 面试题大致可以分成四个层次基础语法层增删改查、聚合函数、多表关联、分组排序。这类问题主要筛选“有没有写过 SQL”。原理理解层索引为什么用 B树、事务隔离级别、MVCC 机制、redo log 与 binlog 的区别。这类问题考察“有没有深入理解数据库”。场景调优层一条慢 SQL 怎么定位、索引失效怎么排查、深分页怎么优化。这类问题考察“有没有处理过真实业务问题”。架构设计层主从复制延迟、分库分表策略、读写分离、大表 DDL。这类问题考察“有没有参与过系统演进”。很多人在索引调优方面卡住核心原因是只记住了结论没有建立“数据结构 → 存储引擎 → 执行计划 → SQL 优化”这条链路。比如面试官问“为什么最左前缀会失效”如果你只回答“因为联合索引的 B树先按第一列排序”这还不够最好能画出索引结构再配合 explain 验证。1.2 为什么索引调优是面试分水岭索引是 MySQL 性能优化中最重要的一环。一张几百万数据的表有索引和没索引查询性能可能相差几十倍。更重要的是索引相关的面试题可以从简单问到难一问索引是什么有哪些类型二问B树和 B-树、哈希表的区别三问什么是回表什么是覆盖索引四问给你一条慢 SQL如何用 explain 分析并优化五问当前业务数据量达到千万级索引策略怎么调整如果只是死记硬背到第三问就容易露馅。本文后续章节会围绕这些高频问题展开给出可以直接用于面试的回答思路。2. 环境准备用一张订单表理解索引索引调优不适合只看理论最好在本地环境跑一遍 explain观察不同 SQL 的执行计划差异。本文示例以 MySQL 8.0 为参考环境如果你使用的是 MySQL 5.7大部分结论仍然适用但个别优化器行为会有细微差别。2.1 创建测试表为了统一理解本节创建一个典型的订单表结构包含用户ID、订单号、订单状态、订单金额、创建时间等字段。这里特意模拟了业务中常见的数据分布。-- 文件路径mysql-index-demo.sql CREATE DATABASE IF NOT EXISTS demo_db DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci; USE demo_db; DROP TABLE IF EXISTS orders; CREATE TABLE orders ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, order_no VARCHAR(64) NOT NULL COMMENT 订单编号, user_id BIGINT UNSIGNED NOT NULL COMMENT 用户ID, status TINYINT NOT NULL DEFAULT 0 COMMENT 订单状态0待支付1已支付2已发货3已完成4已取消, amount DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 订单金额, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no), KEY idx_user_id (user_id), KEY idx_create_time (create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci COMMENT订单测试表;这里需要注意的是主键选择自增 BIGINT避免 UUID 作为主键导致页分裂。唯一索引uk_order_no保证订单号不重复这条约束本身也可以用于查询加速。普通索引idx_user_id和idx_create_time是为了模拟常见查询场景。2.2 插入模拟数据为了测试索引效果可以插入 10 万条左右的数据。生产环境不建议用存储过程批量插数据但测试环境为了模拟数据分布可以用简单的循环插入。-- 文件路径mysql-index-demo.sql DROP PROCEDURE IF EXISTS insert_orders_data; DELIMITER $$ CREATE PROCEDURE insert_orders_data(IN total INT) BEGIN DECLARE i INT DEFAULT 1; START TRANSACTION; WHILE i total DO INSERT INTO orders (order_no, user_id, status, amount, create_time) VALUES ( CONCAT(SN, LPAD(i, 10, 0)), FLOOR(1 RAND() * 10000), FLOOR(RAND() * 5), ROUND(RAND() * 1000, 2), DATE_ADD(2025-01-01 00:00:00, INTERVAL FLOOR(RAND() * 600) DAY) ); SET i i 1; END WHILE; COMMIT; END$$ DELIMITER ; CALL insert_orders_data(100000);存储过程执行时间取决于机器性能10 万条数据通常几十秒内可以完成。插入完成后可以先统计一下数据量确认测试环境正常。SELECT COUNT(*) FROM orders;2.3 创建测试环境的意义有了这份测试数据后面章节中提到的索引失效、回表、覆盖索引、慢 SQL 定位都可以通过EXPLAIN直接观察。建议你也亲手执行一遍不要只在脑内模拟因为 MySQL 优化器在不同数据分布下会选择不同的执行计划自己跑出来的结果往往比背理论更有说服力。3. 高频面试50问全景清单市面上常见的“MySQL 面试夺命 50 问”版本很多但真正有效的清单应该按知识模块划分而不是随便堆砌题目。下面按索引、事务、锁、SQL 优化、架构与引擎六个方向整理成 50 个问题前带【】表示面试中最高频的核心题目。3.1 索引与存储结构15问【高频】什么是索引索引的底层数据结构为什么选择 B树【高频】B树与 B-树、红黑树、哈希表的区别是什么【高频】聚簇索引和非聚簇索引有什么区别【高频】什么是回表查询如何避免回表【高频】什么是覆盖索引【高频】什么是联合索引什么是最左前缀原则【高频】为什么联合索引需要考虑字段顺序什么是唯一索引允许 NULL 吗什么是前缀索引适用场景是什么什么是索引下推ICP为什么 InnoDB 表建议使用自增主键主键索引和普通索引的叶子节点分别存储什么为什么不能对所有列都建立索引什么是索引选择性怎么计算什么是自适应哈希索引3.2 事务与隔离级别10问【高频】事务的 ACID 分别指什么【高频】MySQL 有哪些隔离级别默认是哪个【高频】脏读、不可重复读、幻读分别是什么【高频】MVCC 的实现原理是什么【高频】快照读和当前读有什么区别redo log 的作用是什么undo log 的作用是什么binlog 和 redo log 有什么区别长事务会带来什么问题事务提交过程中两阶段提交是什么3.3 锁机制8问【高频】表锁和行锁的区别是什么【高频】InnoDB 的行锁是基于什么实现的什么是间隙锁间隙锁如何解决幻读【高频】死锁产生的原因是什么如何避免乐观锁和悲观锁在数据库中怎么实现MySQL 中SELECT ... FOR UPDATE的作用是什么什么是 next-key lock锁等待超时参数有哪些3.4 慢SQL与执行计划10问【高频】如何定位一条慢 SQL【高频】EXPLAIN 中的 type 字段每个值代表什么【高频】EXPLAIN 中的 Extra 字段有哪些常见值【高频】索引失效的场景有哪些最左前缀索引一定不会失效吗深分页问题怎么优化JOIN 查询如何优化ORDER BY 如何利用索引COUNT(*) 和 COUNT(1) 有什么区别为什么SELECT *不推荐3.5 主从复制与架构4问主从复制的原理是什么主从复制延迟如何解决读写分离要注意什么分库分表有哪些拆分策略3.6 存储引擎与运维3问【高频】InnoDB 和 MyISAM 的区别是什么Buffer Pool 的作用是什么在线大表 DDL 有哪些方案以上 50 问基本覆盖了 MySQL 面试的常考范围。接下来不按题目顺序平铺直叙而是围绕最核心的索引调优、事务锁、慢 SQL 优化三大块详细拆解。掌握这些内容后再回头逐题自查效果会更好。4. 核心原理拆解索引必考知识点索引相关的面试题与其背答案不如先理解 B树、聚簇索引、回表、最左前缀、索引下推这五个核心概念。它们是整个索引知识体系的基础。4.1 为什么是B树B树是一种多路平衡搜索树InnoDB 选择 B树作为索引结构主要是基于磁盘 IO 和范围查询两个维度考虑矮胖结构B树非叶子节点不保存数据每个节点可以存储更多索引项树的高度通常在 2 到 4 层。即使千万级数据量查询也只需要几次磁盘 IO。双向链表B树叶子节点通过指针连接非常适合范围查询比如WHERE create_time BETWEEN ... AND ...。稳定查询性能无论查询哪一条数据都必须从根节点走到叶子节点路径长度相对一致性能更可控。对比其他数据结构B-树非叶子节点也存储数据导致单节点能存储的索引项更少树更高磁盘 IO 会增加。红黑树本质是二叉树高度明显高于 B树不适合大规模数据范围查询。哈希表单条记录等值查询极快但不支持范围查询也无法排序。面试时可以这样回答B树结合了磁盘预读特性减少了磁盘 IO 次数同时叶子节点的链表结构天然适合范围扫描所以 InnoDB 索引选择了 B树。4.2 聚簇索引、回表与覆盖索引InnoDB 中聚簇索引就是主键索引它的叶子节点保存整行数据。非聚簇索引二级索引的叶子节点保存的是主键值不是完整行数据。当用户通过二级索引查询时流程是先扫描二级索引的 B树找到目标主键值。再根据主键值去聚簇索引中查找整行数据。第 2 步就是“回表”。如果查询的字段恰好都存在于二级索引中就不需要回表这种场景叫做覆盖索引。例如SELECT user_id, status FROM orders WHERE user_id 10086;如果存在联合索引idx_user_status (user_id, status)那么这条 SQL 可以直接从二级索引返回结果不需要回表。这也是为什么联合索引设计得好可以显著降低查询成本。面试回答要点先说回表是什么再说覆盖索引如何避免回表最后补充“实际项目中覆盖索引常用于高频查询的字段裁剪”。4.3 最左前缀原则联合索引(a, b, c)在 B树中的排序规则是先按 a 排序a 相同再按 b 排序b 相同再按 c 排序。因此查询条件中必须包含 a 列索引才会被有效利用。例如对于索引idx_user_status (user_id, status)-- 可以使用索引 SELECT * FROM orders WHERE user_id 10086 AND status 1; -- 可以使用索引只走 user_id 前缀 SELECT * FROM orders WHERE user_id 10086; -- 无法有效使用索引缺少 user_id SELECT * FROM orders WHERE status 1;这里需要注意最左前缀并不要求条件中必须出现所有索引字段只要出现了最左边的列就能用到索引的一部分。同时如果有范围查询比如a 5 AND b 1b 通常无法继续利用索引因为 B树先按 a 排序a 是范围时 b 无法保证有序。这是面试中容易深挖的细节。4.4 索引下推索引下推Index Condition PushdownICP是 MySQL 5.6 引入的优化。简单说就是在遍历二级索引时尽量把部分 WHERE 条件下推到存储引擎层在索引遍历过程中过滤减少回表次数。假设有联合索引(user_id, status)执行SELECT * FROM orders WHERE user_id BETWEEN 1 AND 100 AND status 1;没有 ICP 时InnoDB 会先扫出user_id BETWEEN 1 AND 100的所有记录逐一回表再在 Server 层过滤status 1。启用 ICP 后可以在索引遍历时直接用status 1过滤只对满足条件的数据回表。面试时提到 ICP能体现出对 MySQL 优化器较深的理解。5. 索引失效场景与验证索引失效是面试必考也是最容易在实际开发中踩坑的部分。下面整理高频索引失效场景并用 explain 验证。5.1 高频失效场景汇总场景示例是否失效对索引列使用函数WHERE DATE(create_time) 2026-01-01失效隐式类型转换WHERE order_no 123456列是 VARCHAR失效前模糊查询WHERE order_no LIKE %SN001%失效OR 连接非索引列WHERE user_id 1 OR amount 100可能失效联合索引不满足最左前缀WHERE status 1索引 idx_user_status失效对索引列进行计算WHERE user_id 100 200失效使用 NOT IN、NOT EXISTS 等WHERE user_id NOT IN (1,2,3)可能退化这里尤其要注意函数操作和隐式类型转换。例如order_no是 VARCHAR如果写成SELECT * FROM orders WHERE order_no 123456;MySQL 会把字符串列转为数字比较导致索引列上发生隐式类型转换索引失效。类似地WHERE DATE(create_time) 2026-01-01对索引列做了函数处理也会失效。正确写法是用范围条件SELECT * FROM orders WHERE create_time 2026-01-01 AND create_time 2026-01-02;5.2 用EXPLAIN验证失效在测试表中执行以下 SQL并通过 explain 查看 type 和 possible_keys 的变化。EXPLAIN SELECT * FROM orders WHERE user_id 10086\G正常情况可以看到typeref命中了idx_user_id。再看一个失效场景EXPLAIN SELECT * FROM orders WHERE DATE(create_time) 2025-03-01\G这条 SQL 通常typeALL说明走了全表扫描。由此可以直观感受到函数操作对索引的影响。5.3 索引失效如何排查遇到 SQL 变慢时建议按以下顺序排查先看 SQL 是否在索引列上做了函数、计算或隐式类型转换。再看查询条件是否满足最左前缀原则。观察 OR 两边的字段是否都有索引。结合 explain 查看 rows 扫描行数是否过大。检查字符集是否一致例如关联查询时两张表字段字符集不同也容易导致索引失效。6. 实战一条慢SQL从定位到优化慢 SQL 优化是 MySQL 面试和项目实战中最重要的综合能力。下面用订单表模拟一个典型的慢查询场景完整演示定位和优化流程。6.1 开启慢查询日志MySQL 8.0 中可以通过以下命令查看慢查询日志相关参数SHOW VARIABLES LIKE slow_query_log%; SHOW VARIABLES LIKE long_query_time;如果慢查询日志未开启可以临时开启SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1; SET GLOBAL log_output TABLE;log_output 设置为 TABLE 后慢 SQL 会记录到mysql.slow_log表方便后续查询。生产环境中开启慢查询日志需要评估磁盘和性能影响建议在测试环境先行验证。6.2 模拟一条慢SQL执行下面这条 SQL查询某个时间段内已支付订单的总额。在没有合适索引时它可能扫描大量数据。SELECT user_id, SUM(amount) AS total_amount FROM orders WHERE status 1 AND create_time 2025-03-01 AND create_time 2025-04-01 GROUP BY user_id;这个案例比较典型where 条件同时包含 status 和 create_time 两个查询列但当前表只有idx_user_id和idx_create_time两个单列索引没有联合索引覆盖该查询。6.3 分析执行计划EXPLAIN SELECT user_id, SUM(amount) AS total_amount FROM orders WHERE status 1 AND create_time 2025-03-01 AND create_time 2025-04-01 GROUP BY user_id\G执行计划中可能出现typeALL或typeindexrows 接近全表数据量。原因是单列索引无法同时高效过滤 status 和 create_time优化器可能选择全表扫描。6.4 建立联合索引针对查询条件建立一个联合索引idx_status_create_timeALTER TABLE orders ADD INDEX idx_status_create_time (status, create_time);注意字段顺序status 是等值条件create_time 是范围条件一般把等值条件字段放在联合索引前面范围字段放后面。这样索引可以先用 status 快速筛选再利用 create_time 的有序性定位范围。6.5 再次验证优化效果重新执行 explainEXPLAIN SELECT user_id, SUM(amount) AS total_amount FROM orders WHERE status 1 AND create_time 2025-03-01 AND create_time 2025-04-01 GROUP BY user_id\G此时 type 通常会变为rangerows 显著减少。这条 SQL 还能进一步优化为覆盖索引ALTER TABLE orders DROP INDEX idx_status_create_time; ALTER TABLE orders ADD INDEX idx_status_create_time_amount (status, create_time, amount);因为查询需要返回 amount 并聚合覆盖索引可以直接在索引叶子节点获取数据减少回表。通过 explain 的 Extra 字段可以看到 USING INDEX说明已经使用了覆盖索引。6.6 优化过程中的注意事项不要盲目加索引。每次新增索引都会影响写入性能需要结合真实业务 SQL 评估。重复索引要清理。例如已有(a, b)联合索引再建一个a单列索引就重复了。生产环境变更索引要注意低峰期大表加索引可能锁表或耗时较长。7. 事务、锁与MVCC面试题中事务和锁经常与隔离级别一起出现。很多同学能背出四种隔离级别但说不清 MVCC 如何实现快照读以及锁如何解决幻读。下面把这部分串起来。7.1 ACID与隔离级别事务的四大特性AAtomicity原子性事务要么全部成功要么全部失败。CConsistency一致性事务执行前后数据库完整性约束不被破坏。IIsolation隔离性并发事务之间不能互相干扰。DDurability持久性事务提交后修改永久生效。SQL 标准定义了四种隔离级别READ UNCOMMITTED读未提交可能发生脏读。READ COMMITTED读已提交解决脏读但不可重复读。REPEATABLE READ可重复读MySQL 默认隔离级别解决不可重复读但可能幻读。SERIALIZABLE串行化通过加锁避免并发问题性能最差。MySQL InnoDB 在 REPEATABLE READ 级别下通过间隙锁和 MVCC 基本解决了幻读问题所以默认隔离级别选择 RR 也符合业务安全需求。7.2 MVCC实现思路MVCCMulti-Version Concurrency Control多版本并发控制核心思想是读操作不加锁通过版本链和 ReadView 实现历史版本读取写操作之间仍然需要加锁。关键组件隐藏字段InnoDB 每行记录有隐藏的trx_id最近修改事务ID和roll_pointer指向 undo log 版本链。undo log保存历史版本数据支持事务回滚和 MVCC 快照读。ReadView事务执行快照读时生成一个视图记录当前活跃事务列表用于判断哪些版本对当前事务可见。常见面试追问快照读普通 SELECT 不加锁通过 ReadView 读取可见版本。当前读SELECT ... FOR UPDATE、UPDATE、DELETE必须读取最新版本并加锁。7.3 锁机制与死锁InnoDB 锁类型可以简单分为表锁锁住整张表粒度大并发低。行锁锁住具体记录InnoDB 通过索引实现行锁。如果 SQL 没有走索引行锁可能升级为表锁。间隙锁锁住两个索引记录之间的区间防止其他事务插入数据。next-key lock记录锁和间隙锁的组合MySQL RR 级别下用于解决幻读。死锁是面试高频题。死锁产生需要四个必要条件互斥、持有并等待、不可剥夺、循环等待。数据库解决死锁的常见方式是检测死锁并回滚代价较小的事务。避免死锁的工程建议多个事务按相同顺序访问表或行。事务尽量短小减少锁持有时间。合理设计索引让 UPDATE/DELETE 走更精确的行锁。控制事务并发数量降低死锁概率。8. 高频MySQL面试题精讲有了前面原理铺垫下面精选几个高频面试题给出完整回答思路。8.1 为什么选择B树而不是哈希表回答思路哈希表等值查询 O(1)但无法处理范围查询和排序。业务 SQL 中范围查询、排序、分组很常见B树可以通过叶子节点链表高效完成。InnoDB 中还有自适应哈希索引用于加速特定等值查询但这是内部优化不能替代 B树。8.2 什么是回表如何避免回答思路回表示通过二级索引查到主键后再回聚簇索引取整行数据的过程。回表不是 bug但回表次数多会增加磁盘 IO。避免回表的方案是使用覆盖索引也就是 SELECT 的字段都包含在索引中。比如高频查询需要查询 status 和 amount可以设计联合索引包含这些字段。8.3 联合索引建立原则回答思路等值条件放前面范围条件放后面。根据查询频率和字段区分度决定字段顺序。考虑用联合索引覆盖高频查询字段减少回表。不要认为索引越多越好联合索引可以替代多个单列索引但要注意最左前缀限制。8.4 COUNT(*) 和 COUNT(1) 的区别回答思路MySQL 8.0 中COUNT(*)和COUNT(1)在语义和使用上性能基本一致。COUNT(字段)只统计该字段非 NULL 的行数可能触发全表扫描或遍历二级索引。大数据量下精确 COUNT 仍然较慢可以结合缓存、汇总表、近似统计等方式优化。8.5 一条SQL执行很慢如何排查回答思路先确认是否命中索引用 EXPLAIN 查看 type、key、rows。检查是否是索引失效场景比如函数操作、隐式类型转换。查看当前表数据量是否数据倾斜、统计信息过旧。检查是否出现锁等待SHOW PROCESSLIST查看事务状态。考虑是否 SQL 本身要返回的数据量过大可以做分页或裁剪字段。必要时开启慢查询日志把历史慢 SQL 捞出来逐一分析。8.6 InnoDB和MyISAM的区别回答思路InnoDB 支持事务、行级锁、外键崩溃恢复能力强MyISAM 不支持事务只支持表锁。InnoDB 的索引和表数据都存储在同一个表空间中聚簇索引组织MyISAM 索引文件和数据文件分离。现在主流选择是 InnoDB除非有特殊只读场景否则不建议用 MyISAM。8.7 深分页如何优化深分页典型问题是LIMIT 100000, 20需要扫描前 100020 条数据再丢弃前 100000 条。常见的优化思路是“延迟关联”或“基于游标的分页”-- 延迟关联思路 SELECT t.* FROM orders t INNER JOIN ( SELECT id FROM orders WHERE create_time 2026-01-01 ORDER BY create_time LIMIT 100000, 20 ) tmp ON t.id tmp.id;子查询只查主键通过索引快速定位再用主键关联回原表减少回表扫描量。另一种方案是通过WHERE create_time ? ORDER BY create_time LIMIT 20实现游标分页适合瀑布流场景。9. 常见问题与排查思路下面整理面试和实际开发中容易遇到的常见问题并给出排查方向。问题现象常见原因解决思路SQL 一直走全表扫描没有创建合适索引或索引失效用 EXPLAIN 确认优先检查函数、隐式转换、最左前缀加了索引还是慢索引选择性低优化器放弃索引计算索引区分度考虑更换字段或使用前缀索引联合索引失效查询条件缺少最左列调整 SQL 条件或索引字段顺序分页很慢LIMIT 偏移量过大延迟关联或游标分页更新语句锁表WHERE 条件没有走索引为更新条件字段创建索引死锁频繁事务访问顺序不一致或锁范围过大统一访问顺序缩短事务缩小锁范围主从延迟大事务、DDL、从库性能不足拆分大事务关注慢 SQL优化从库配置COUNT 很慢数据量大且无优化方案使用汇总表、缓存或弱一致统计排查 MySQL 性能问题时不建议一上来就调整数据库服务器参数。优先检查 SQL 本身和索引设计因为大部分性能问题都源于不合理的 SQL 或缺失的索引。10. 最佳实践与面试回答技巧最后这部分汇总 MySQL 索引调优和面试准备的工程建议。10.1 索引设计建议在业务项目中设计索引时可以参考下面几条每个表索引数量不宜过多一般不要超过 5 到 6 个否则写入性能会明显下降。优先为 WHERE 条件、ORDER BY、GROUP BY 涉及的字段创建索引。区分度低的字段如 status、sex不建议单独建索引但可以放在联合索引中配合等值筛选。使用联合索引替代部分单列索引避免冗余。对于很长的字符串字段使用前缀索引降低索引大小。生产环境索引变更要评估锁表时间尽量使用在线 DDL 工具或低峰期执行。定期用SHOW INDEX FROM table检查重复索引和未使用索引。10.2 面试回答的结构化技巧面试官问到 MySQL 问题尤其是索引优化相关时回答尽量采用“结论先行 原理说明 场景举例”的结构。例如先给出结论这条 SQL 慢大概率是因为没有走索引。再补充原理二级索引叶子节点存主键回表造成扫描量放大。最后给方案建立联合索引通过覆盖索引减少回表。如果现场能口述 explain 中 type、key、rows、Extra 的变化面试官会认为你具备真实调优经验。10.3 学习路线建议如果你的目标是系统掌握 MySQL 面试知识建议按以下顺序学习先熟悉 SQL 基础语法和常用函数。再理解 InnoDB 存储结构重点是 B树。学习聚簇索引、回表、覆盖索引、最左前缀。在本地搭建测试环境多跑 EXPLAIN 对比执行计划。继续学习事务、MVCC、锁。最后学习主从复制、分库分表等生产架构知识。这 50 个问题不用一天背完最好分模块消化。每学完一个模块就回到文章开头的清单里把对应问题口头回答一遍。如果在项目里有真实慢 SQL 优化经验建议整理成案例面试时比单纯背八股更有说服力。
返回列表