Skip to content

2026-06-22 MySQL 三题拷问复盘

本轮结果

  • 综合评分:76/100
  • 是否过关:否
  • 结论:主干概念基本有,但机制层和项目落地口径不够稳定,尤其 MVCC 可见性判断和 Redis -> MySQL 最终兜底链路还需要再压实。

第 1 题:MySQL 索引为什么快,什么是回表、覆盖索引、最左前缀

你的回答摘要

  • 能答出 B+ 树、回表、覆盖索引、最左前缀的基本定义。
  • 能回答二级索引不存整行的一个主要收益:树更矮、单页能放更多键。
  • (a,b,c) 联合索引的几个典型条件,能判断出 b,c 脱离最左列时无法充分利用索引,范围查询后后续列利用会变差。

缺失点

  • “索引为什么快” 还偏定义层,没有把 “低树高 -> 更少磁盘 IO -> 范围查询友好” 压成一段完整口径。
  • 最左前缀答到了规则,但还没把底层原因讲成 “联合索引按 (a,b,c) 复合键排序,a 全局有序,b/c 只是局部有序”。
  • 没有连接到项目里的慢查询、回表成本或索引设计场景。

推荐答案

MySQL 索引快,核心是 InnoDB 底层一般采用 B+ 树。非叶子节点只存键和值指针,所以单页能放更多索引项,树高更低,查一次数据通常只需要很少几层,磁盘 IO 成本更低。二级索引叶子节点存的是主键值,所以查到主键后还要去聚簇索引拿整行,这就是回表;如果查询字段本身就在索引里,就形成覆盖索引,可以直接返回结果,避免回表。联合索引 (a,b,c) 本质是按复合键整体排序,所以必须从最左边开始连续利用;一旦中间断开或者遇到范围条件,后续列就很难继续完整利用索引排序能力。

项目口径

黑马点评 里,这题最好能顺带落到 “为什么热点业务表要尽量做覆盖索引、减少回表随机 IO”,以及 “为什么联合索引设计要贴着真实筛选条件来建,而不是机械把字段都塞进去”。

后续状态

  • 训练中

第 2 题:事务隔离级别和 MVCC 是怎么配合工作的

你的回答摘要

  • 知道 MVCC 主要工作在 RC/RR
  • 知道 RC 每次读新建快照,RR 复用第一次快照。
  • 知道快照读和当前读是两类不同场景。

缺失点

  • 对 “一行数据为什么可见” 的底层机制不稳,trx_idReadViewundo log 三者分工没能一次性说完整。
  • 对 “MVCC 管可见性,锁机制管当前读并发控制” 这条边界还不够熟。
  • 回答过度依赖补缺后短版,面试里再追一层容易断。

推荐答案

MVCC 主要解决快照读的可见性问题。每行数据会带隐藏字段,比如最后修改它的事务 ID;当前事务做快照读时会基于活跃事务列表生成 ReadView;如果当前版本对这张 ReadView 不可见,InnoDB 就顺着回滚指针去 undo log 找更早的版本。RCRR 的核心区别就是 ReadView 的生成时机不同:RC 每次快照读都生成新的 ReadView,所以能看到其他事务后续提交的新值;RR 复用事务里第一次快照读的 ReadView,因此同一事务内快照读结果更稳定。要注意,MVCC 主要管快照读可见性,当前读场景下的幻读控制更多靠间隙锁和临键锁。

项目口径

黑马点评 或订单类场景里,这题的落点不是背隔离级别表格,而是说明:普通查询为什么能少加锁、更新或 select ... for update 为什么又必须交给锁机制兜底。

后续状态

  • 待返工

第 3 题:Redis 扛高并发,MySQL 保最终一致性

你的回答摘要

  • 知道 Redis 更适合抗高并发入口流量,MySQL 才是真实落库点。
  • 补缺后能说出 重试重复消费状态漂移 这三个风险。
  • 能说出数据库兜底至少要有条件更新和联合唯一索引。

缺失点

  • 初答还停留在 “MySQL 有事务,所以它兜底” 的泛化表达,没落到具体约束。
  • 对 “为什么 Lua 已经原子了,库层还不能放弃抵抗” 这条工程边界不够稳。
  • 项目化口径还不够像面试回答,缺少 “库存条件更新防超卖、联合唯一索引防重复单” 这种短句。

推荐答案

Redis 承担的是入口抗并发和前置校验,比如预扣减、判重、异步削峰,但 Redis 到 MySQL 之间还会经过服务调用和 MQ,这里可能出现重试、重复消费、状态漂移,所以不能只信上游判断。MySQL 是最终真实数据落点,至少要做两类兜底:一类是幂等兜底,比如订单表上的联合唯一索引,防止一人多单或重复回调;一类是边界兜底,比如 update ... set stock = stock - 1 where id = ? and stock > 0 这样的条件更新,物理上拦住超卖。这样即使前面的 Redis 或 MQ 出问题,数据库也不会把脏结果真正落进去。

项目口径

黑马点评 秒杀场景里,可以直接答成:Redis 的 Lua 脚本负责挡住并发洪峰,MySQL 的 stock > 0 条件更新负责最后防超卖,user_id + voucher_id 唯一索引负责最后防重复下单,两层一起才算闭环。

后续状态

  • 待返工

来源知识卡片

下次复习动作

  • 先口述 2 遍 “联合索引 (a,b,c) 为什么必须走最左前缀”,重点练 “全局有序 / 局部有序” 这句。
  • 单独再刷一轮 MVCC,强制把 trx_id + ReadView + undo log + RC/RR 压成 30 秒版。
  • 再刷一次 Redis -> MySQL 兜底链路,只答三句话:风险是什么、库层兜底是什么、项目里怎么落。