MySQL 高频面试题(由浅到深 完整版,面试必背)
一、基础核心篇(初级 / 中级必问,重中之重,面试保底分,占比 40%)
1. MySQL 是什么?核心特点有哪些?
答案要点 MySQL 是一款开源的关系型数据库(RDBMS),基于 SQL 语言,主打轻量、高性能、高可用、易部署,是互联网行业首选的数据库(电商、金融、社交等 90% 以上业务都在用)。核心特点:
- 支持关系型数据库特性:ACID 事务、外键、约束、多表关联查询。
- 高性能:底层优化优秀,支持海量数据存储,单表千万级数据查询依然高效。
- 多存储引擎:支持插件式引擎,最常用
InnoDB(默认)、MyISAM。 - 高可用:支持主从复制、读写分离、集群部署,避免单点故障。
- 跨平台:支持 Linux/Windows/Mac,适配所有主流服务器系统。
2. MySQL 中 InnoDB 和 MyISAM 存储引擎的区别?(【必考】高频中的高频,必须背会)
✅ 核心结论:MySQL5.5 及以后,默认存储引擎是 InnoDB,InnoDB 是事务安全型引擎,MyISAM 是性能型引擎,MyISAM 已被官方逐步淘汰。
3. char 和 varchar 的区别?varchar (5) 和 varchar (200) 的区别?(高频坑点)
答案要点 二者都是字符串类型,核心区别是存储方式和长度固定性,面试必问第二个问题,是经典坑点!
✔ 一、char 与 varchar 核心区别
- char(n):定长字符串,n 代表固定长度(0-255)。
- 特点:无论存入多少字符,都会占用
n个字符的空间,不足补空格;查询速度极快,适合短字符串、长度固定的场景。 - 适用:手机号、身份证号、性别、状态码(如 0/1)。
- 特点:无论存入多少字符,都会占用
- varchar(n):变长字符串,n 代表最大长度(0-65535)。
- 特点:实际占用空间 = 真实字符长度 + 1/2 个字节(存储长度),不会补空格;查询速度略慢于 char,适合长度不固定的长字符串。
- 适用:用户名、商品标题、描述、地址等。
✔ 二、面试坑点:varchar(5) 和 varchar(200) 存储 "abc" 的区别?
✅ 标准答案:存储上无区别,性能上几乎无区别
- 存储:两者存入 "abc" 时,实际占用的字节数完全相同,都是
3 + 1个字节。 - 性能:MySQL 只会校验「是否超过最大长度」,不会因为定义的长度大而浪费空间 / 变慢。
- 注意:不要无脑定义
varchar(255/65535),要按需定义,避免字段长度溢出、索引失效。
4. datetime 和 timestamp 的区别?(高频考点)
答案要点 二者都是日期时间类型,核心区别是存储范围、时区支持、占用空间:
- datetime:占 8 字节,存储范围
1000-01-01 ~ 9999-12-31,不支持时区转换,存入什么时间就显示什么时间,不受数据库时区影响。 - timestamp:占 4 字节,存储范围
1970-01-01 ~ 2038-01-19,支持时区转换,存入时会转成 UTC 时间,查询时按当前时区转回,占用空间更小。适用场景:业务无时区需求 → 用 datetime;有跨国 / 跨时区需求 → 用 timestamp;推荐用 datetime,避免 2038 年溢出问题。
5. 主键、唯一索引、普通索引、外键的区别?(必考)
✔ 核心定义 + 区别
- 主键索引(Primary Key)
- 特性:一张表只能有一个主键,主键字段非空 + 唯一,InnoDB 中主键是聚簇索引,数据按主键排序存储,查询效率最高。
- 作用:唯一标识一条记录,是表的核心索引。
- 唯一索引(Unique Key)
- 特性:一张表可以有多个唯一索引,索引字段唯一但可以为空(最多一个 null)。
- 作用:保证字段值的唯一性,如手机号、邮箱、用户名。
- 普通索引(Index)
- 特性:一张表可以有多个普通索引,字段值可重复、可空,无约束性。
- 作用:单纯提升查询速度,是最常用的索引类型,如商品标题、订单编号。
- 外键索引(Foreign Key)
- 特性:建立两张表的关联关系,外键字段的值必须是另一张表的主键值,保证数据的参照完整性。
- 注意:生产环境慎用外键,会降低增删改效率,一般在业务层保证关联完整性即可。
✔ 面试加分
- 主键可以是唯一索引,唯一索引不一定是主键;
- 主键字段建议用自增整型(int/bigint),不要用字符串,提升索引效率。
6. 什么是索引?索引的作用?为什么索引能提升查询速度?
答案要点
✔ 索引定义
索引是 MySQL 的一种特殊数据结构(B + 树),建立在表的一个或多个字段上,索引存储了字段的值和对应的行数据地址,相当于表的「目录」。
✔ 索引的核心作用
- 提升查询速度:通过索引快速定位到数据行,避免全表扫描(核心作用);
- 加速排序 / 分组:索引本身是有序的,order by/group by 时可直接用索引排序,无需额外排序;
- 保证数据唯一性:主键、唯一索引可以约束字段唯一性。
✔ 索引提速的本质
- 无索引:查询时是全表扫描,逐行匹配条件,时间复杂度
O(n); - 有索引:通过 B + 树的有序结构,二分查找定位数据,时间复杂度
O(logn); - 类比:查字典时,通过拼音目录找字,比逐页翻字典快百倍。
✔ 索引的缺点(面试必答,体现思考深度)
索引不是越多越好,有优点必有缺点,这是面试加分项:
- 增删改变慢:数据变更时,需要同步维护索引结构,索引越多,维护成本越高;
- 占用磁盘空间:索引是独立的文件,会占用额外的磁盘空间;
- 过度索引会导致索引失效:不合理的索引会让 MySQL 优化器选择错误的索引。
7. 最左匹配原则是什么?(索引核心考点,必考)
答案要点(必须背会,面试满分答案)
- 定义:最左匹配原则是 联合索引的核心规则,当创建
(a,b,c)的联合索引时,MySQL 会优先匹配索引的最左侧字段,并依次向右匹配,跳过的字段会导致索引失效。 - 核心规则:
- 支持:
where a=1、where a=1 and b=2、where a=1 and b=2 and c=3→ 全匹配索引; - 失效:
where b=2、where c=3、where b=2 and c=3→ 跳过了最左的 a,索引完全失效; - 部分生效:
where a=1 and c=3→ a 字段走索引,c 字段不走索引(中间跳过 b)。
- 支持:
- 延伸规则:联合索引中,范围查询(>、<、like)后的字段会失效。
- 例如:
where a=1 and b>2 and c=3→ a、b 走索引,c 字段失效。
- 例如:
✅ 面试结论:创建联合索引时,把查询频率最高、筛选性最强的字段放在最左侧。
二、进阶原理篇(中 / 高级必问,拉开面试差距,核心考点,占比 35%)
1. MySQL 索引的底层数据结构是什么?为什么用 B + 树,不用 B 树 / 哈希 / 红黑树?(【天花板考点】必考,面试分水岭)
答案要点(标准答案,分点作答,面试满分)
✔ 一、InnoDB 索引的底层结构:B + 树
- 普通索引:叶子节点存储「字段值 + 主键值」;
- 主键索引(聚簇索引):叶子节点存储「主键值 + 整行数据」,这是 InnoDB 的核心特性。
✔ 二、为什么 MySQL 选择 B + 树,不选其他结构?(核心必答,体现原理功底)
✅ 对比 1:为什么不用【哈希索引】?
哈希索引是键值对映射,查询效率 O(1),看似更快,但有致命缺陷,MySQL 仅 Memory 引擎支持:
- 哈希索引只支持等值查询(=、in),不支持范围查询(>、<、like、between);
- 哈希索引是无序的,无法用于排序(order by);
- 哈希冲突:哈希值相同的字段会形成链表,冲突严重时查询效率暴跌。
✅ 对比 2:为什么不用【二叉树 / 红黑树】?
- 二叉树:极端情况下会退化成单链表,查询效率从
O(logn)变成O(n),完全失效; - 红黑树:属于平衡二叉树,但树的高度过高,千万级数据时树高可达几十层,磁盘 IO 次数过多(索引在磁盘上,每层对应一次 IO)。
✅ 对比 3:为什么不用【B 树】,而用 B + 树?
B 树和 B + 树都是多路平衡树,核心区别在叶子节点,B + 树是 B 树的优化版,完美适配 MySQL 的磁盘存储,优势有 3 点:
- B + 树的非叶子节点只存索引,不存数据:一页能存更多索引,树的高度更低,磁盘 IO 次数更少(MySQL 中一次 IO 对应一页数据,树高越低越快);
- B + 树的叶子节点是双向链表:支持范围查询,这是 B 树没有的核心优势(如查询 id 100-200,B + 树直接遍历链表即可);
- B + 树的查询效率稳定:所有查询都要走到叶子节点,查询时间固定,B 树的查询时间不固定。
✅ 面试总结:B + 树完美适配 MySQL 的「磁盘 IO」和「范围查询」两大核心需求,是最优解。
2. MySQL 事务的四大特性(ACID)?(必考,基础中的基础)
答案要点(背诵即可,分点清晰)事务是数据库中一组不可分割的 SQL 操作,要么全部执行成功,要么全部失败回滚,事务的核心是四大特性,简称 ACID:
- 原子性(Atomicity):事务中的所有操作,是一个整体,要么全成功,要么全回滚,不存在部分执行的情况(核心:不可分割)。
- 例:转账时,A 扣款、B 加款,要么都成功,要么都失败。
- 一致性(Consistency):事务执行前后,数据库的数据完整性、业务规则保持不变(核心:数据正确)。
- 例:转账前后,A+B 的总金额不变;订单创建后,库存数减少对应数量。
- 隔离性(Isolation):多个事务并发执行时,事务之间相互隔离,互不影响,每个事务感觉不到其他事务的存在(核心:互不干扰)。
- 隔离性由「事务隔离级别」和「锁机制」保证,解决并发事务的脏读、不可重复读、幻读问题。
- 持久性(Durability):事务提交后,修改的数据会永久写入磁盘,即使数据库崩溃重启,数据也不会丢失(核心:永久生效)。
- 持久性由 MySQL 的redo 日志保证。
3. 并发事务会产生哪些问题?MySQL 的事务隔离级别有哪些?默认是哪个?(【必考】高频核心,重中之重)
✅ 核心逻辑:事务隔离级别就是为了解决并发事务的三大问题,隔离级别越高,并发问题越少,性能越低。
✔ 一、并发事务的三大问题(按严重程度排序)
- 脏读:事务 A 读取到了事务 B未提交的数据,之后 B 回滚,A 读到的数据是「脏数据」,完全无效。
- 不可重复读:事务 A 中,多次读取同一数据,期间事务 B 修改并提交了该数据,导致 A 多次读取的结果不一致(针对修改 / 更新操作)。
- 幻读:事务 A 中,多次执行同一查询条件的 SQL,期间事务 B 新增 / 删除了符合条件的数据,导致 A 查询的结果条数不一致,像出现了「幻觉」(针对新增 / 删除操作)。
✔ 二、MySQL 的 4 种事务隔离级别(按隔离强度从低到高排序,必背)
所有隔离级别都基于 SET TRANSACTION ISOLATION LEVEL 级别名 设置,MySQL 默认隔离级别:可重复读(RR),Oracle 默认:读已提交(RC)。
- 读未提交(READ UNCOMMITTED):最低级别,允许读取未提交的数据 → 存在脏读、不可重复读、幻读,几乎不用。
- 读已提交(READ COMMITTED,RC):只能读取其他事务已提交的数据 → 解决脏读,存在不可重复读、幻读。
- 可重复读(REPEATABLE READ,RR):MySQL默认级别,同一个事务内,多次读取同一数据结果一致 → 解决脏读、不可重复读,理论存在幻读,实际被 InnoDB 解决了 ✅。
- 串行化(SERIALIZABLE):最高级别,事务串行执行,完全禁止并发 → 解决所有问题,但性能极差,适合并发量极低的场景(如金融对账)。
✔ 面试加分:MySQL 的 RR 级别,为什么能解决幻读?
✅ 标准答案:InnoDB 在 RR 级别下,通过 「间隙锁 + 临键锁」的组合(Next-Key Lock),锁住了数据的「行 + 区间」,彻底阻止了其他事务的新增 / 删除操作,从而解决了幻读问题。
4. InnoDB 的锁机制?行锁、表锁、乐观锁、悲观锁的区别?(必考,核心考点)
✔ 一、InnoDB 的两种核心锁(按粒度划分)
InnoDB 是行锁为主、表锁为辅的存储引擎,这也是它并发性能远超 MyISAM 的核心原因,锁的粒度越小,并发越高。
- 行级锁:锁住表中的某一行数据,其他事务可以操作表中其他行,并发性能极高。
- 触发条件:必须命中索引,如果查询没有走索引,行锁会升级为表锁!(经典坑点,必答)
- 分类:共享锁(S 锁,读锁)、排他锁(X 锁,写锁),读锁之间兼容,读写锁互斥,写写锁互斥。
- 表级锁:锁住整张表,其他事务无法操作表中的任何数据,并发性能极差。
- 触发条件:无索引查询、全表扫描、执行 alter table 等 DDL 语句时触发。
✔ 二、乐观锁 & 悲观锁(按锁的思想划分,业务开发必考)
这是业务层的锁机制,不是数据库原生锁,面试必问,也是生产中解决并发问题的核心方案,两者无优劣,按需选择。
- 悲观锁(Pessimistic Lock)
- 核心思想:悲观的认为,每次操作都会有并发冲突,所以在操作数据前,先锁住数据,直到操作完成才释放锁。
- 数据库实现:
select ... for update(排他锁),select ... lock in share mode(共享锁)。 - 适用场景:写多读少的高并发场景(如库存扣减、订单创建、转账),并发冲突概率高。
- 优点:简单粗暴,能保证数据一致性;缺点:加锁会有性能开销,可能导致死锁。
- 乐观锁(Optimistic Lock)
- 核心思想:乐观的认为,每次操作都不会有并发冲突,所以操作数据时不加锁,只在提交时判断数据是否被修改过。
- 实现方式:版本号法(推荐),在表中加
version字段,更新时判断版本号是否一致:update table set name='xxx', version=version+1 where id=1 and version=2。 - 适用场景:读多写少的场景(如商品详情查询、用户信息修改),并发冲突概率低。
- 优点:无锁开销,性能极高;缺点:无法解决 100% 的并发冲突,冲突时需要业务层重试。
✅ 面试结论:写多读少用悲观锁,读多写少用乐观锁,这是生产环境的最优选型。
5. MySQL 三大日志(redo log、undo log、binlog)的区别和作用?(必考,源码级考点)
MySQL 的三大日志是保证数据安全、事务一致性、主从复制的核心,三者缺一不可,面试必问,也是理解 InnoDB 的关键,必须分清楚三者的作用和区别。
✔ 一、redo log 重做日志(InnoDB 独有,事务持久性的保证)
- 核心作用:保证事务的 持久性(ACID-D),解决「数据库崩溃后数据丢失」的问题。
- 工作原理:InnoDB 是内存数据库,数据修改先写入内存的 buffer pool,再异步刷盘到磁盘。为了防止内存数据丢失,每次执行写操作时,都会先把修改记录写入 redo log,如果数据库崩溃,重启后会通过 redo log 恢复数据,保证数据不丢失。
- 特点:物理日志(记录「哪个页修改了什么内容」)、循环写入(固定大小,写满覆盖)、事务提交时刷盘。
✔ 二、undo log 回滚日志(InnoDB 独有,事务原子性的保证)
- 核心作用:保证事务的 原子性(ACID-A),实现「事务回滚」和「MVCC 多版本并发控制」。
- 工作原理:执行写操作时,InnoDB 会先把「修改前的数据」写入 undo log,当事务执行失败需要回滚时,通过 undo log 恢复到修改前的状态;同时,undo log 也存储了数据的历史版本,供 MVCC 读取。
- 特点:逻辑日志(记录「执行了什么反向操作」)、可回滚、支持多版本。
✔ 三、binlog 归档日志(MySQL 服务器层日志,所有引擎都支持)
- 核心作用:实现 主从复制 和 数据备份 / 恢复,是 MySQL 分布式架构的核心。
- 工作原理:记录所有的DDL 和 DML 语句(建表、增删改),以二进制形式存储,主库的 binlog 会同步到从库,从库执行 binlog 中的语句,实现主从数据一致。
- 特点:逻辑日志、追加写入(写满新建文件,不覆盖)、有三种格式(STATEMENT/ROW/MIXED),生产推荐 ROW 格式。
✔ 三者核心区别(面试必答,满分答案)
- 归属不同:redo/undo 是InnoDB 引擎层日志,binlog 是MySQL 服务器层日志;
- 作用不同:redo 保证持久化,undo 保证原子性,binlog 保证主从同步;
- 写入方式不同:redo 循环写,undo/binlog 追加写;
- 内容不同:redo 是物理日志,undo/binlog 是逻辑日志。
6. 什么是 MVCC?实现原理是什么?(中高级必考,加分项)
答案要点(精简版,面试够用,不啰嗦)
- 定义:MVCC = 多版本并发控制,是 InnoDB 在RR 级别下实现的一种无锁并发控制机制,核心是「读不加锁,读写不冲突」,极大提升并发性能。
- 核心思想:为每一行数据维护多个历史版本,不同事务读取不同版本的数据,事务修改数据时,不会覆盖原数据,而是生成新的版本,旧版本通过 undo log 保存。
- 实现原理:基于 undo log(历史版本)+ 事务 ID + ReadView(可见性规则) 实现,简单说就是:事务读取数据时,通过 ReadView 判断哪些版本的数据对当前事务可见,从而读取到一致的数据,无需加锁。
- 优势:解决了「读锁和写锁的互斥问题」,读操作不用加锁,写操作只加行锁,并发性能大幅提升。
三、高级优化 & 实战篇(资深 / 架构师必问,高薪考点,拔高面试档次,占比 25%)
1. MySQL 慢查询优化的完整步骤?(【实战必考】面试压轴题,背会就是加分)
✅ 核心:面试时回答这个问题,一定要分步骤、有逻辑,体现你有完整的问题排查和优化思路,这是企业最看重的实战能力!
慢查询优化 6 步黄金法则(必背,生产通用,万能答案)
步骤 1:开启慢查询日志,定位慢 SQL
- 开启慢查询:
slow_query_log = ON,设置慢查询阈值:long_query_time = 1(执行时间 > 1 秒的 SQL 为慢查询); - 查看慢查询日志:
show slow logs,或用工具mysqldumpslow分析日志,找到执行时间长、扫描行数多的慢 SQL。
步骤 2:用 EXPLAIN 分析慢 SQL 执行计划(核心)
- 执行
EXPLAIN + 慢SQL,查看执行计划的关键字段:type、key、rows、Extra; - 核心判断标准:✔
type:查询类型,最优是const,其次是eq_ref、range、ref,最差是ALL(全表扫描,必须优化);✔key:是否命中索引,为NULL表示无索引,需要创建索引;✔rows:扫描的行数,行数越少越好;✔Extra:出现Using filesort(文件排序)、Using temporary(临时表)、Using index(覆盖索引)是关键优化点。
步骤 3:优化索引(最常用、最有效的优化手段)
- 针对无索引的慢 SQL:创建合适的索引(主键、唯一、普通、联合索引);
- 针对索引失效的 SQL:修复索引失效问题(见下文考点 2);
- 针对冗余索引:删除无用的索引,避免索引过多导致优化器选择错误。
步骤 4:优化 SQL 语句本身(避坑,核心)
- 避免写复杂的多表关联,拆分 SQL;
- 避免使用
select *,只查需要的字段,实现「覆盖索引」; - 避免使用
%xxx模糊查询(左模糊会导致索引失效); - 避免使用
in、not in、or,改用exists、union all; - 大表分页优化:
select * from table where id>10000 limit 10替代limit 10000,10。
步骤 5:优化表结构
- 大表拆分:垂直拆分(按字段)、水平拆分(按数据量);
- 优化数据类型:用小类型替代大类型(如 tinyint 替代 int,varchar 替代 text);
- 分表分库:单表数据量超过千万级时,考虑分库分表。
步骤 6:优化 MySQL 配置参数
- 调优内存相关参数:
innodb_buffer_pool_size(设置为物理内存的 50%-70%)、join_buffer_size、sort_buffer_size; - 调优连接相关参数:
max_connections、wait_timeout; - 调优日志相关参数:
innodb_log_file_size、binlog_cache_size。
2. 索引失效的 10 种常见场景 + 解决方案?(高频坑点,必背)
✅ 核心:索引失效的本质是 MySQL 优化器认为走索引的效率,不如全表扫描高,所以放弃使用索引,所有失效场景都围绕这个核心。
索引失效场景(按高频度排序,前 8 种必考)
- 查询条件中使用函数 / 运算:
where abs(id)=10、where name like concat('%', 'abc')→ 索引失效;✔ 解决:避免在索引字段上做函数 / 运算,业务层处理后再查询。 - 左模糊查询:
where name like '%abc'→ 索引失效,where name like 'abc%'→ 索引生效;✔ 解决:业务上尽量用右模糊,必须左模糊则用全文索引。 - 联合索引不遵循最左匹配原则:跳过最左字段,索引失效;✔ 解决:按最左匹配原则编写查询条件,调整联合索引的字段顺序。
- 查询条件中使用!= 或 <>:
where id != 10→ 索引失效;✔ 解决:尽量用=替代,必须用则业务层过滤。 - 查询条件中使用 is null /is not null:索引字段为 null 时,索引失效;✔ 解决:字段设置为
not null,默认值为空字符串 / 0。 - 使用 in /not in /or:
where id in (1,2,3)、where id=1 or name='abc'→ 索引失效;✔ 解决:小数据量 in 可用,大数据量用exists替代;or 改用union all。 - 数据分布不均:如性别字段只有 0/1,创建索引后也不会生效(区分度太低);✔ 解决:不创建索引,直接全表扫描。
- 查询条件没有命中索引:行锁升级为表锁,索引失效;✔ 解决:为查询条件创建合适的索引。
- 隐式类型转换:如字段是 int 类型,查询时传字符串:
where→ 索引失效;✔ 解决:保证查询条件的类型和字段类型一致。 - 优化器选择错误:MySQL 优化器误判,选择全表扫描而非索引;✔ 解决:用
force index(索引名)强制走索引。
3. 大表如何优化?单表数据量多大需要优化?(实战必考)
✔ 一、优化阈值
- 行业共识:单表数据量超过 1000 万行 或 表文件超过 10G,查询性能会急剧下降,必须优化;
- 核心原因:索引树的高度过高,磁盘 IO 次数增多,查询变慢。
✔ 二、大表优化的 6 种方案(按优先级排序,生产通用,必背)
✅ 方案 1:优先做「非分表优化」(成本最低,见效最快,首选)
- 加合适的索引:避免全表扫描,这是最基础的优化;
- 优化 SQL:避免
select *、避免大表关联、优化分页查询; - 冷热数据分离:将历史冷数据(如 3 年前的订单)归档到历史表,主表只保留近期热数据;
- 开启分区表:按时间 / 范围分区,查询时只扫描对应分区,如
partition by range (id),对业务无侵入。
✅ 方案 2:分表优化(数据量过大,必选)
当非分表优化无效时,进行分表,分表分为两种,按需选择:
- 垂直分表:按字段拆分,把大表拆成多个小表,如把订单表拆成「订单基本信息表」和「订单详情表」;
- 适用:表的字段过多,部分字段查询频率低。
- 水平分表:按数据行拆分,把大表拆成多个结构相同的小表,如把订单表按用户 ID 哈希拆成 10 张表;
- 适用:表的行数过多,超过千万级。
✅ 方案 3:分库分表(终极方案)
当单库的存储和性能达到瓶颈时,采用分库分表,主流中间件:Sharding-JDBC(轻量,推荐)、MyCat;
- 核心规则:按哈希 / 范围 / 时间分片,如按用户 ID 哈希分库,按订单时间范围分表。
4. MySQL 主从复制的原理?主从延迟的原因和解决办法?(架构必考)
✔ 一、主从复制的核心原理(3 步,必背)
MySQL 主从复制是异步复制,核心是基于 binlog 日志实现,架构是「一主多从」,主库写,从库读,实现读写分离、负载均衡、数据备份,是 MySQL 高可用的基础:
- 主库:主库执行写操作后,将 SQL 语句写入
binlog日志; - 从库:从库的 IO 线程连接主库,读取主库的 binlog 日志,写入本地的
relay log中继日志; - 从库:从库的 SQL 线程读取中继日志,执行其中的 SQL 语句,实现主从数据一致。
✔ 二、主从延迟的原因 + 解决方案(面试必答,生产高频问题)
✅ 主从延迟的核心原因
- 主库的写操作并发量高,binlog 日志生成速度快,从库的 SQL 线程处理速度跟不上;
- 从库的硬件配置比主库差,CPU / 内存 / 磁盘性能不足;
- 主库执行大事务(如批量更新、大表导入),导致 binlog 日志量大,从库执行慢;
- 主从复制是异步的,天生存在延迟。
✅ 主从延迟的解决方案(按优先级排序,必背)
- 提升从库配置:让从库的硬件配置和主库一致,甚至更好;
- 减少大事务:拆分大事务为小事务,避免一次性执行大量 SQL;
- 半同步复制:开启
rpl_semi_sync_master,主库提交事务后,等待至少一个从库接收 binlog 后再返回,减少延迟; - 并行复制:从库开启多线程并行执行 SQL,提升同步速度;
- 业务层优化:对实时性要求高的查询,强制走主库,非实时查询走从库。
5. 什么是死锁?死锁的产生原因和解决办法?(必考)
✔ 一、死锁的定义
死锁是指两个或多个事务,互相持有对方需要的锁,同时等待对方释放锁,导致所有事务都无法继续执行,陷入无限等待的状态。
- 例:事务 A 锁住了行 1,等待行 2 的锁;事务 B 锁住了行 2,等待行 1 的锁 → 死锁。
✔ 二、死锁的产生条件(4 个,缺一不可)
- 互斥:同一时刻,一个锁只能被一个事务持有;
- 持有并等待:事务持有一个锁,同时申请另一个锁;
- 不可抢占:锁只能由持有事务主动释放,不能被其他事务抢占;
- 循环等待:事务之间形成循环的锁等待关系。
✔ 三、死锁的解决办法(预防 + 解决,必背)
✅ 预防死锁(首选,成本最低)
- 统一事务的加锁顺序:所有事务都按相同的顺序获取锁,如先锁行 1,再锁行 2,避免循环等待;
- 减少锁的持有时间:事务尽量短小,快速执行完释放锁,避免长时间持有锁;
- 尽量用行锁,少用表锁:行锁的粒度小,冲突概率低;
- 避免大事务:大事务会持有锁很长时间,增加死锁概率。
✅ 解决死锁(发生后处理)
- MySQL 会自动检测死锁,并回滚其中一个事务(代价最小的那个),释放锁;
- 手动处理:通过
show engine innodb status查看死锁日志,定位死锁的事务和 SQL,优化业务逻辑。
✅ 面试加分小技巧(最后必看)
- MySQL 面试的核心是 「索引 + 事务 + 锁 + 优化」,这四个模块占比 90%,吃透即可应对所有面试;
- 回答问题时,分点作答,逻辑清晰,比如慢查询优化、索引失效场景,面试官会觉得你基础扎实、思路清晰;
- 遇到原理题(如 B + 树、主从复制),不用讲源码细节,讲清楚核心流程和优势即可,面试官要的是你的理解能力,不是背诵能力;
- 所有优化类问题,都要遵循「先低成本,后高成本」的原则,比如大表优化先做索引和 SQL 优化,再做分表分库。