MySQL 面试专题:高频考点深度解析
先说结论(简单直白)再讲原理(深入解释)最后扩展(举例 + 面试官可能追问的方向)索引(B+ 树、最左前缀、覆盖索引)事务(ACID、MVCC、锁)执行计划(EXPLAIN)日志(redo、undo、binlog)SQL 优化案例。
·
MySQL 面试专题:高频考点深度解析

面试中 MySQL 是必考点,既考察基础(索引、事务),也会深挖原理(B+ 树、锁机制、执行计划)。
下面我们从 高频面试问题 出发,逐个拆解,并提供 答案思路 + 深入细节 + 扩展提问。
一、索引相关
1. 为什么 InnoDB 使用 B+ 树而不是 B 树 / 哈希索引?
答题思路:
- B 树存储数据在每个节点,非叶子节点也存数据,可能导致一次磁盘 IO 拿不到完整范围数据。
- B+ 树只在叶子节点存储数据,非叶子节点只存索引,层数更少,磁盘 IO 更少。
- B+ 树叶子节点之间有链表,适合范围查询。
- 哈希索引适合点查,不支持范围查询和排序。
扩展问法:
- 如果主键是自增 ID 和 UUID,B+ 树索引的存储区别是什么?
👉 自增 ID 插入有序,B+ 树分裂少;UUID 随机,会导致页分裂和碎片,性能差。
2. 联合索引的最左前缀原则是什么?
答题思路:
- 假设索引
(a, b, c),可以用到(a)、(a, b)、(a, b, c),也能用(a, c)吗?答案是 不能。 - 因为索引是按照最左字段依次排序的,必须连续匹配。
扩展问法:
- 如果有
WHERE a=1 AND c=2,会用到索引吗?
👉 可以用到a,但c不能用到索引,需要额外过滤。
3. 覆盖索引是什么?
答题思路:
- 覆盖索引 = 查询所需字段都在索引里,不需要回表。
- 优点:减少一次回表 IO,提高查询性能。
举例:
SELECT id, name FROM users WHERE id = 100;
如果有索引 (id, name),直接从索引里拿,不需要再回到表里。
二、事务与锁
1. 事务的四大特性(ACID)是什么?
- A(原子性):事务要么全部成功,要么全部失败(undo log 保证)。
- C(一致性):事务前后数据满足约束条件。
- I(隔离性):事务之间互不干扰。
- D(持久性):事务提交的数据会持久保存(redo log 保证)。
扩展问法:
- MySQL 是如何保证原子性和持久性的?
👉 undo log 保证原子性,redo log + binlog 保证持久性。
2. MySQL 的事务隔离级别有哪些?
- 读未提交(RU):可能读到未提交数据(脏读)。
- 读已提交(RC):避免脏读,但可能不可重复读。
- 可重复读(RR,InnoDB 默认):避免脏读 + 不可重复读,但可能幻读。
- 串行化(Serializable):强制事务串行执行,性能差。
扩展问法:
- InnoDB 在 RR 下是如何避免幻读的?
👉 MVCC + Next-Key Lock(间隙锁)。
3. 行锁和表锁的区别?
- 行锁:粒度小,冲突少,开销大。InnoDB 支持。
- 表锁:粒度大,冲突多,开销小。MyISAM 使用。
扩展问法:
- 什么时候 InnoDB 也会锁全表?
👉 没有索引时,UPDATE/DELETE会退化成全表锁。
三、执行计划与优化
1. EXPLAIN 输出中 type 字段的含义?
- const:常量查询,效率最高。
- eq_ref:唯一索引等值连接。
- ref:非唯一索引等值。
- range:范围查询。
- index:全索引扫描。
- ALL:全表扫描,最差。
👉 面试高频:如何优化 ALL?
- 建索引
- 改写 SQL
- 分库分表
2. Extra 字段里出现 Using filesort / Using temporary 怎么办?
- Using filesort:说明排序没用到索引,可以用 索引优化 order by。
- Using temporary:说明 group by 用了临时表,可以用 索引优化 group by 或 物化视图。
四、日志与存储
1. redo log 和 binlog 的区别?
- redo log(InnoDB 特有):物理日志,记录数据页的修改,用于 crash recovery。
- binlog(Server 层):逻辑日志,记录 SQL 语句或行变更,用于主从复制和数据恢复。
两阶段提交保证一致性:
- 写 redo log (prepare)
- 写 binlog
- redo log (commit)
2. undo log 的作用?
- 提供回滚(保证原子性)。
- 提供多版本快照(MVCC,保证一致性和隔离性)。
五、综合案例:面试常见 SQL 优化题
题目:
有一张 orders 表(千万级数据),字段如下:
id (PK)
customer_id
status
order_date
amount
请优化以下 SQL:
SELECT * FROM orders WHERE status = 1 AND order_date > '2023-01-01' ORDER BY order_date;
思路:
- 加复合索引
(status, order_date)。 - 如果查询字段很少,可以用覆盖索引
(status, order_date, amount)。 - 如果只取最近数据,加
LIMIT减少结果集。 - 避免
SELECT *,只取需要字段。
六、总结:面试回答套路
- 先说结论(简单直白)
- 再讲原理(深入解释)
- 最后扩展(举例 + 面试官可能追问的方向)
👉 面试官常问的问题几乎都围绕:
- 索引(B+ 树、最左前缀、覆盖索引)
- 事务(ACID、MVCC、锁)
- 执行计划(EXPLAIN)
- 日志(redo、undo、binlog)
- SQL 优化案例
更多推荐


所有评论(0)