1. 面试真题整体观:某大厂OD技术面MySQL到底考什么
1.1 面试官出题逻辑:从一条慢SQL说起
关于某大厂OD技术面里的数据库MySQL环节,想先给各位交个底。它不像很多人想象的那样,一上来就深挖原理、逼你背八股。我面试过的候选人里,被淘汰的往往不是基础差,而是“知道结论,不知道结论是怎么来的”。
比如最常见的一类开局:
“你有一条SQL特别慢,怎么排查?”
这问题听着简单,但面试官后面会连环追问:Explain里哪些字段值得看?为什么明明建了索引还是慢?索引失效是优化器的问题还是索引本身的问题?到了事务部分又会问:可重复读下真的能完全避免幻读吗?一条update语句从发起到提交,日志是怎么配合的?主从延迟到底怎么治?
这些问题串起来,基本就是MySQL面试的主干。到了第三篇真题,我们要聊的不再是“索引是什么”这种入门题,而是围绕“能不能把一条SQL调好、能不能把一个事务讲透、能不能把一次故障恢复讲清楚”来展开。适合正在准备这类岗位面试、或者日常工作里要和慢SQL、死锁、主从延迟打交道的人。
1.2 高频考点清单:第三辑为什么聚焦这几个模块
我整理了一下近期收集到的同类型面试反馈,MySQL部分的高频考察点非常集中,几乎可以画成一张能力地图。
| 考察模块 | 典型问法 | 需要达到的理解深度 |
|---|---|---|
| 索引与SQL优化 | “这条SQL怎么建索引最快?” | 能从执行计划反推索引结构 |
| 事务与隔离级别 | “脏读、不可重复读、幻读分别什么场景?” | 能从MVCC层面解释隔离实现 |
| 锁机制 | “两个事务同时更新同一行怎么办?” | 能说清行锁、间隙锁、死锁 |
| 日志机制 | “一条update执行后MySQL突然宕机,重启后数据怎么恢复?” | 能讲透redo、undo、binlog配合 |
| 主从复制 | “从库延迟太严重,怎么处理?” | 能结合binlog格式和并行复制说明 |
| 分库分表 | “单表两千万数据,你怎么拆分?” | 能给出分片键、扩容、一致性方案 |
这一辑的编排顺序,其实就是我建议大家的复习顺序:先把SQL优化解决掉,因为这是最直观的加分项;然后攻事务和锁,因为这里最容易露怯;最后看日志和高可用,这部分答好了,面试官会觉得你有生产环境经验。
2. 索引与SQL优化:笔试和手撕题的重灾区
2.1 一条慢SQL的完整优化实录
先拿一个我经常拿来练手的场景。假设有一张订单表,结构大致如下:
CREATE TABLE `user_order` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `user_id` BIGINT NOT NULL, `order_no` VARCHAR(64) NOT NULL, `amount` DECIMAL(10,2) DEFAULT NULL, `status` TINYINT DEFAULT NULL, `created_at` DATETIME NOT NULL, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_created_at` (`created_at`) ) ENGINE=InnoDB;业务上有个高频查询:查某个用户最近的20条订单。
SELECT id, user_id, order_no, amount, status, created_at FROM user_order WHERE user_id = 1001 ORDER BY created_at DESC LIMIT 20;乍一看,user_id上有索引,created_at上也有索引,好像没问题。但实际跑一下会发现,当这个用户的下单记录很多时,这条SQL会越来越慢。用Explain看一眼:
type: ref key: idx_user_id rows: 8000 Extra: Using filesort问题就出在Extra: Using filesort上。MySQL先按idx_user_id找到这个用户的所有记录,然后还要对created_at做一次排序,这个排序发生在内存或磁盘的临时文件里。用户订单量越大,排序代价越高。
这种场景的常规解法是联合索引:
ALTER TABLE `user_order` ADD KEY `idx_user_created` (`user_id`, `created_at`);建完以后Explain的Extra变成了Using index condition,filesort消失了,因为联合索引的第二个字段已经天然按created_at排好序。查询直接从索引定位到该用户的最早或最新位置,顺序扫描即可。
我实际测下来,在百万级数据量、单用户几千条订单的场景下,这条SQL的耗时能从几十毫秒降到个位数毫秒。但这里只是第一层优化,如果业务还要查金额、状态等列呢?Using filesort没了,但可能还会回表。所以下一层要解决的是覆盖索引和回表问题。
2.2 索引失效的十大套路与底层原因
面试里关于索引失效的题,本质上是考察你对B+树有序性的理解。索引为什么失效,不是记规则,而是看“破坏有序性”和“无法定位区间”这两个核心。
我自己归纳了十个高频场景,每个都在实际生产或实验环境里踩过:
- 对索引列使用函数,比如
WHERE DATE(created_at) = '2025-01-01'。索引存的是原始DATETIME值,函数运算把比较基准变了,走不了树搜索。 - 隐式类型转换,比如订单号是VARCHAR,SQL里写成
order_no = 202501011234,MySQL会把字符串列转成数字再比较,索引失效。 - 前导模糊查询,
LIKE '%abc'。B+树只能按前缀匹配定位,前导通配符破坏了前缀定位能力。 - OR条件连接了非索引列,比如
user_id=1001 OR status=1。优化器很难组合多个索引范围,可能退化成全表扫描。 - 联合索引里范围查询右侧的列失效。索引
(a,b)在a>1 AND b=2时,b列没法精确匹配,因为B+树先按a排序再按b排序,a的范围跨越导致b不再有序。 NOT IN、!=、<>,优化器经常认为全表扫描代价更低,特别数据量不大时。- 排序字段和索引顺序、方向不一致。
ORDER BY a DESC, b ASC在联合索引(a ASC, b ASC)下可能无法直接利用。 - 索引列参与运算,
WHERE id + 1 = 10,索引列的非独立形式,本质上和函数一样。 - 某些情况下
IS NOT NULL无法使用索引,取决于优化器判断的区分度。 - JOIN的两表字符集不一致,导致隐式字符集转换,索引失效。
记忆这些规则没有用,关键是面试官追问“为什么”时,你能说出“因为索引树的节点按索引列原始值有序排列,任何包装、运算、转换都会让这个顺序失效”。
2.3 回表、覆盖索引与ICP:面试官常说的“深入一点”
“回表”这个概念,是区分初中级开发的一道分水岭。简单说,InnoDB的二级索引叶子节点存的是索引列值和主键值。查询如果除了索引列还需要其他列时,就要拿着主键再去主键的B+树里查一次完整行,这个动作就是回表。
比如上面的SQL,即使有了(user_id, created_at)联合索引,SELECT里还有order_no、amount、status,这些列不在索引中,所以每一条符合条件的记录都要回表。回表是随机I/O,如果命中几千行,代价就很可观。
解决办法之一是覆盖索引:把需要的列都塞进索引。
ALTER TABLE `user_order` ADD KEY `idx_user_created_cover` (`user_id`, `created_at`, `order_no`, `amount`, `status`);这样查询需要的字段全部在二级索引里,Extra会显示Using index,不需要回表。代价是索引占空间更大,写入也变慢,所以实际应该按高频查询设计,而不是一股脑加列。
ICP是另一个容易被忽略的点。MySQL 5.6以后支持的索引条件下推,允许存储引擎在索引层面先过滤一部分数据,再回表。比如复合索引(user_id, created_at),查询user_id=1001 AND created_at > '2025-01-01',在没有ICP时是先按user_id把主键都取出来回表,再在Server层过滤created_at;有了ICP,存储引擎会在索引里先把created_at过滤掉,减少回表次数。Explain的Extra显示Using index condition,这个细节很多候选人讲不清楚,但你一旦说出来,面试官通常都会加分。
3. 事务、隔离级别与MVCC:概念不能只背口诀
3.1 四种隔离级别到底隔离了什么
事务隔离级别的题,最怕背口诀。背得出“读未提交有脏读、读已提交解决脏读、可重复读解决不可重复读、串行化解幻读”只是第一层,真正拉开差距的是下面的解释。
先说脏读。读未提交下,一个事务能读到另一个事务还没提交的修改,一旦对方回滚,你读到的数据就是“脏”的。读已提交把这一点堵住了,只认已提交版本。
再说不可重复读。同一事务内两次SELECT,读到其他事务已提交的修改,前后结果不一致。注意这里不是“读到了脏数据”,而是“数据内容变了”。读已提交下会出现,可重复读下不会。
最后是幻读。同一事务内两次范围查询,第二次多出几行记录,原因是其他事务插入了符合条件的新数据。可重复读并不能天然杜绝幻读,InnoDB的解法是MVCC加临键锁组合,这块下面专门讲。
面试官很喜欢问:“你实际生产环境用的是什么隔离级别?”如果项目里用的是MySQL默认的REPEATABLE READ,你要能解释为什么选它,以及它和读已提交在生产上的差异。很多团队会为了减少死锁改成READ COMMITTED,这是合理决策,但面试官想听的是“你知道两者在锁和MVCC上的差别”。
3.2 一条更新语句在事务里经历了什么
这道题是面试官最爱的综合性问题。把一条UPDATE拆开,能串联起Buffer Pool、Undo Log、Redo Log、Binlog、锁、两阶段提交。
假设事务里执行:
UPDATE user_order SET amount = 100 WHERE id = 200;大致流程是这样的:
- 找到id=200的行。如果不在Buffer Pool,先从磁盘读入。
- 对这行加上排他锁,防止其他事务并发修改。
- 把修改前的旧值写入Undo Log,方便回滚和MVCC快照。
- 更新内存中的记录,这行数据变成脏页。
- 生成Redo Log,记录“在哪个页的哪个偏移量做了修改”,先写入Redo Log Buffer。
- 事务提交时,Redo Log进入prepare状态,写入Binlog并落盘。
- Binlog落盘成功,Redo Log再从prepare转成commit状态。
这里最有价值的点是两阶段提交。为什么不能先写Binlog再写Redo,或者反过来?因为两份日志记录的是不同层次的东西:Binlog是Server层逻辑日志,Redo是InnoDB物理日志。如果崩溃发生在中间状态,不一致会造成主从数据对不上。
我自己的记忆方法是:Redo像施工方的施工记录,Binlog像监理方的验收记录,两份记录必须对得上账,施工才算完成。
3.3 MVCC实现原理与快照读/当前读
MVCC的全称是多版本并发控制。InnoDB实现它,靠的是每行记录里两个隐藏字段:DB_TRX_ID(最近修改该行的事务ID)和DB_ROLL_PTR(指向Undo Log中旧版本链的头节点)。
事务做快照读时,会生成一个ReadView。ReadView里主要包含四部分:创建视图时活跃事务ID列表、列表最小值、下一个将要分配的事务ID、当前事务自己的ID。判断某行是否可见,就是拿DB_TRX_ID和这几个值比大小。
可重复读和读已提交的核心区别在于ReadView的创建时机。读已提交是每次SELECT都重新生成ReadView,所以能看到其他事务已提交的新版本;可重复读是事务里第一次快照读时创建ReadView,之后整个事务复用同一个视图,于是读不到其他事务提交的新版本。
这里有个容易被问倒的点:快照读和当前读。普通SELECT是快照读,靠Undo Log版本链读取历史版本。UPDATE、DELETE、INSERT以及SELECT ... FOR UPDATE、SELECT ... LOCK IN SHARE MODE都是当前读,读的是最新已提交版本,并且加锁。
理解了快照读和当前读,才能真正理解可重复读下的幻读。快照读阶段靠ReadView保证一致性快照,所以看不到新插入的行。但如果一个事务先快照读、再执行当前读,当前读是能看到其他事务已经提交的新行的,这时就会出现幻读现象。InnoDB真正在RR隔离级别下禁止幻读的手段,是当前读配合的临键锁,锁住记录和间隙,防止其他事务在范围内插入新记录。
4. 锁机制:从表锁到行锁的面试问答
4.1 锁的类型与兼容矩阵
MySQL锁这块,面试官考察点很集中,但我发现很多人把概念混在一起。这里给一张我总结的对应关系。
从粒度看,有表级锁和行级锁。InnoDB支持行锁,MyISAM只有表锁。行锁又分成共享锁(S锁)和排他锁(X锁),兼容关系很简单:
| 锁类型 | 共享锁(S) | 排他锁(X) |
|---|---|---|
| 共享锁(S) | 兼容 | 冲突 |
| 排他锁(X) | 冲突 | 冲突 |
InnoDB还有一个很容易在面试里被忽略的表级意向锁。事务想在某行加S锁,得先在表上加意向共享锁;想加X锁,得先加意向排他锁。意向锁的作用是让后续表锁操作快速判断表里是否有行被锁住,不用遍历所有行。
再往细里分,行锁在实现上有三种形态:
- 记录锁(Record Lock):锁住索引记录本身。
- 间隙锁(Gap Lock):锁住两个索引记录之间的区间,防止其他事务在这个区间插入数据。
- 临键锁(Next-Key Lock):记录锁加间隙锁的组合,既锁记录又锁区间。
间隙锁是解决幻读的关键,也是生产环境死锁的高发原因。它能防止INSERT插入到间隙中,但也可能锁住本不存在的记录范围,导致无谓阻塞。
4.2 死锁排查与模拟案例
死锁的经典戏码是两个事务交替锁住对方下一步要用的资源。我把这个案例记得很牢,因为它面试讲起来特别直观。
事务A先执行:
UPDATE inventory SET stock = stock - 1 WHERE product_id = 1;事务B先执行:
UPDATE inventory SET stock = stock - 1 WHERE product_id = 2;然后事务A接着更新product_id=2,事务B接着更新product_id=1。A持有1等待2,B持有2等待1,双方都不放手,InnoDB死锁检测立即介入,回滚代价较小的一方。
排查死锁的现场操作我提一个实用命令:
SHOW ENGINE INNODB STATUS\G在输出里找LATEST DETECTED DEADLOCK这一段,能看到两个事务的执行SQL、持有的锁和等待的锁,以及被回滚的事务。生产环境如果频繁出现死锁,先收集这个信息再定位业务代码,别盲目加索引或改SQL。
预防死锁的实用手段有三件套:一是让所有事务按相同顺序访问资源,比如都先更新product_id小的再更新大的;二是缩小事务体量,把不必要的查询从事务里挪出去,减少锁持有时间;三是用乐观锁重试机制代替悲观锁,减少互相等待。
4.3 锁等待超时与热点行更新优化
除了死锁,锁等待超时也是一个高频问题。默认参数innodb_lock_wait_timeout是50秒,如果事务A持锁不提交,事务B等锁超过了这个时间就会报超时错误。
我在生产环境见过一个典型的坑:秒杀场景里所有请求都更新同一个商品的库存,事务一个个排队,但每个事务里还夹杂着很多慢查询,锁持有时间被拉长,后面的请求大量超时。
这种热点行的优化思路,从根上说不是拼命调大锁等待时间,而是减少持锁时间。实务里常用的方案包括:
- 把大事务拆小,库存扣减单独一个短事务,其他非核心逻辑放事务外。
- 用原子UPDATE而不是先SELECT再UPDATE,避免不必要的锁范围扩大。
- 考虑库存预扣和异步对账,把热点写操作从数据库压力中剥离。
- 热点行排队严重时,用Redis做扣减,DB异步落账,DB只负责最终一致性。
面试官如果想考这部分,往往会顺着“热点更新”往分布式方向引。能说出“数据库层面只能等待,必须从业务架构上分流”这句话,基本就过关了。
5. 日志与崩溃恢复:答好这道题直接加分
5.1 binlog、redo log、undo log 三者的分工
日志机制是MySQL面试里性价比最高的考点,因为它串起了事务、复制、恢复三个大模块。很多人只知道三份日志的名字,却说不出为什么需要三份。
Binlog是MySQL Server层产生的二进制日志,记录的是逻辑变更,比如“更新了哪一行、变成什么值”。它的核心用途有两个:主从复制和基于时间点的数据恢复。Binlog是追加写的,不会覆盖历史。
Redo Log是InnoDB存储引擎层的物理逻辑日志,记录的是“数据页做了什么修改”。它解决的是崩溃恢复问题:事务提交后,数据页可能还在内存里没刷到磁盘,如果这时候宕机,要靠Redo Log重放,保证已提交事务不丢失。Redo Log是循环写的,文件固定大小,写满会覆盖。
Undo Log则是事务回滚和MVCC的基础,记录的是“修改前的旧值”。事务发生回滚时,要按Undo Log恢复旧版本。
三道日志各管一摊:Undo保证原子性,Redo保证持久性,Binlog负责归档和复制。面试时能一句话概括,再配合update流程展开,印象分很高。
5.2 redo log刷盘与性能取舍
Redo Log并不是每次提交都立刻刷到磁盘。MySQL通过参数innodb_flush_log_at_trx_commit控制刷盘策略,这个参数是面试官爱问的生产配置。
三个取值对应三种权衡:
- 0:提交时不刷盘,由后台线程每秒刷一次。性能最好,但崩溃时可能丢失最后一秒内的已提交事务。
- 1:每次事务提交都刷盘。最安全,不会丢已提交事务。
- 2:每次提交只写入操作系统缓存,每秒再fsync刷盘。崩溃时操作系统没宕的话不丢,宕机可能丢。
生产环境默认推荐1,因为数据安全性优先。但对高并发写场景,每次提交都fsync会成为瓶颈。MySQL为此做了组提交(Group Commit),多个事务的Redo Log刷盘合并成一次I/O,大大降低了频繁fsync的代价。
实际调优时还会配合sync_binlog一起调。它的取值为1时,每次提交事务都会把Binlog刷到磁盘,保证Binlog不丢。如果想追求极致性能,有人会设成0或100,但这是把双刃剑,掉电可能丢Binlog,进而导致主从不一致,我不建议线上乱调。
5.3 “更新后突然断电”怎么答
这道题几乎是一道必考综合题,建议每个人都在本地把流程完整推演一遍。
假设事务已经提交,binlog也落盘了,但数据页还没刷到磁盘,这时断电。重启后,InnoDB先扫描Redo Log,把记录了但未应用的重做操作重放,已提交数据不会丢失。
假设事务还没提交,只写了Redo Log Buffer但没进入commit,断电重启。Redo Log里可能只有prepare记录,没有完整commit记录。恢复时MySQL会在崩溃恢复阶段检查Binlog是否完整:如果Binlog里对应事务也完整,说明主从库都可能已经应用,于是提交这个事务;如果Binlog不完整,说明这个事务没被完整记录,就回滚。
这就是两阶段提交的用处。它的存在保证了Redo Log和Binlog的状态一致。答题时把“prepare-commit”和“检查Binlog完整性”这两个关键动作讲出来,和只背日志概念的候选人差距立刻就出来了。
6. 主从复制与高可用:实战题最后一道防线
6.1 复制原理与三种复制格式
主从复制是生产环境绕不开的话题,也是MySQL面试的常规压轴。基础流程要能顺畅讲出:
主库把变更写入Binlog。主库上有Dump线程,负责把Binlog发送给从库。从库上有两个线程:IO线程负责接收Binlog并写入本地的Relay Log;SQL线程负责读取Relay Log并重放,让从库数据追上主库。
这中间最容易被追问的是Binlog格式。MySQL的Binlog有三种格式:
| 格式 | 特点 | 风险 |
|---|---|---|
| STATEMENT | 记录SQL语句本身 | 函数、存储过程等可能在主从库执行结果不一致 |
| ROW | 记录每一行变更前后内容 | 最安全,但Binlog体积大 |
| MIXED | 默认用STATEMENT,遇到不安全SQL自动切ROW | 折中选择 |
实际生产我更推荐ROW格式。虽然体积大,但可回溯性强,误操作后还能从Binlog里反推出原始数据,做闪回恢复也更方便。面试里说“因为ROW能精确记录行变更,避免主从数据不一致”,比笼统回答更到位。
6.2 主从延迟的排查与解决
主从延迟是面试官最喜欢结合实际问的题。它的表象是从库落后主库几千秒,本质是复制通道消费不过来。
常见的延迟原因有三个层次:
第一层是主库写入压力太大。主库的Binlog生成速度超过从库SQL线程的重放速度,尤其是从库SQL线程在旧版本MySQL里是单线程的,一个大事务能拖垮追进度。
第二层是大事务。比如一次性UPDATE十万行,MySQL在从库重放时要一条条或分段执行,其他小事务全部排队等。
第三层是硬件和参数问题。从库磁盘I/O慢、网络带宽不够、从库开着Binlog又没优化刷盘,都会放大延迟。
解决办法也分层:
- 从MySQL 5.7开始启用并行复制,配置
slave_parallel_workers大于1,让多个SQL线程并行重放不同事务,能明显缓解延迟。 - 避免大事务,把批量更新拆成小批次。
- 从库临时关闭或调整
sync_binlog、innodb_flush_log_at_trx_commit,减少刷盘开销。 - 如果业务允许,从库加独立的临时表、内存配置调整,保证足够Buffer Pool。
- 对延迟高度敏感的场景,考虑半同步复制,主库等待从库确认收到Binlog再返回,降低数据丢失概率。
面试里如果能补一句“延迟是必然存在的,读写分离架构要考虑数据最终一致性,比如用户刚下单立刻去查订单可能查不到”,会让面试官觉得你有真实业务经验。
6.3 分库分表与中间件选型
单表数据量过亿、写入吞吐打不上去,就得聊分库分表了。这块不是MySQL自身能力,而是架构方案,但面试题里经常出现,因为它考验的是综合设计能力。
分库分表分两类:垂直拆分和水平拆分。垂直拆分是把一张宽表按业务字段拆成多张表,比如把订单基本信息、订单扩展信息拆开,减少单行数据宽度。水平拆分是把同一张表的数据按规则分散到多张表,比如按user_id取模分16张表。
水平拆分最关键的是分片键选择。分片键必须贴近高频查询条件,否则每个查询都要全库路由,性能反而更差。比如订单表经常按user_id查,就以user_id做分片键;如果还经常按order_no查,就需要维护一份order_no到user_id的映射,或者建全局索引表。
分库分表的会带来分布式主键、跨库JOIN、分布式事务、扩容数据迁移问题。
主键不能用数据库自增,常见是雪花算法或号段模式。跨库JOIN尽量拆成多次单表查询,在应用层组装。分布式事务可以用本地消息表、事务消息或TCC框架。扩容最怕的是按取模分片导致数据全部重排,所以很多新项目选择一致性哈希或按时间范围分片,降低挪动成本。
这题想要答出深度,一定要避免上来就喊“我们用中间件”。先评估数据量和业务形态,再决定是分库还是分表、选什么分片键、用什么中间件,这才是面试官真正想看到的思维。
7. 避坑清单:我在面试中翻过的车和总结
7.1 四道典型真题的“满分回答模板”
这里整理四道我在面试实战里见过的高频真题,每道给出一个答题骨架,不追求完美,但保证逻辑完整。
第一题:排查一条慢SQL。
答题顺序建议是:先确认慢查询日志或压测表现,拿到SQL;再用Explain看执行计划,重点关注type、key、rows、Extra四项;根据结果判断是全表扫描、用了索引但回表太多、还是filesort;再对症下药,能建联合索引就建,能改SQL写法就改;最后用执行计划前后对比验证优化效果。
第二题:可重复读下为什么还有幻读风险。
答题思路是:区分快照读和当前读;快照读靠ReadView保证一致性快照,不会看到新插入的行;当前读读最新版本,如果没间隙锁保护,两次当前读之间可能插入新行,造成幻读;InnoDB通过临键锁锁住范围和间隙来阻止插入。要强调“完全杜绝”要看场景,MVCC加锁组合之下,正常的RR隔离级别事务不会出现幻读,但锁冲突会上升。
第三题:主从延迟怎么办。
从原因入手:先看有没有大事务、是不是单线程复制、从库有没有刷盘瓶颈;再给方案:拆大事务、开并行复制、调整刷盘参数、必要时上半同步;最后补充业务兜底:延迟敏感场景强制走主库或短期容忍最终一致。
第四题:如何设计分库分表。
不要一上来就设计,先问数据量、查询模式、写入峰值;再从垂直拆分和水平拆分里选方向;分片键选高频等值查询字段;考虑数据倾斜、扩容、全局表和分布式事务;最终给出从单库到分库分表的平滑迁移路径,比如双写方案。
7.2 复习顺序与资料建议
MySQL面试准备最忌讳东一榔头西一棒子。我自己的复习路线是:
第一周先把SQL执行流程、索引结构、执行计划吃透。不要求背代码,但要做到给你一条SQL能准确说出它大概怎么走。
第二周攻事务隔离级别、MVCC、锁。这块要画图理解,把ReadView、锁兼容矩阵、死锁场景画出来,比纯文字记忆有效得多。
第三周看日志和主从复制。建议在本地用Docker起一个主从环境,手动停库、重启、观察恢复行为。实践一遍之后,很多概念自然就记住了。
资料方面,MySQL官方文档是最准确的,适合当字典;《高性能MySQL》适合系统阅读,但不用全书逐字啃,挑索引、事务、复制这几章重点看。另外多收集真实面试场景的追问链,自己对着镜子讲一遍,你会发现很多“以为懂”的知识其实经不起推敲。
最后说一点个人体会。MySQL面试题看似零散,其实暗含一条主线:面试官想确认的不是你会背多少概念,而是遇到一个数据库问题时,你能不能找到根因、能不能给出可落地的方案。搞清楚锁和日志的底层逻辑,再结合自己的真实项目场景去演练,比刷一百道填空题有用得多。我建议你在准备期间,哪怕只是临时搭个单机环境,也要亲手造一次慢SQL、造一次死锁、看一次主从延迟,这比任何资料都值得花时间。