MySQL高频面试八连问(附场景化解析)
文章目录
- "为什么订单查询突然变慢了?"——从这个问题开始说起
- 一、索引的生死时速(必考题!)
- 二、事务的"套娃"艺术
- 三、锁机制的相爱相杀
- 四、存储引擎的抉择
- 五、慢查询的破案技巧
- 六、分页的深度优化
- 七、高可用架构的基石
- 八、性能调优的终极武器
- 最后的大实话
“为什么订单查询突然变慢了?”——从这个问题开始说起
上周帮学弟复盘面试时,他提到最怕遇到这种开放性问题:“我们的订单表查询突然变慢,可能是什么原因?该怎么优化?”(面试官超爱这种场景题!!!)今天我们就以这个典型问题为引子,拆解MySQL必考的8大核心知识点。
一、索引的生死时速(必考题!)
面试官连环问:
- 你建的索引为什么失效了?
- 什么情况下索引会失效?
- 如何查看SQL的执行计划?
高频翻车场景:
-- 致命陷阱1:隐式类型转换
SELECT * FROM orders WHERE order_no = 10086; -- order_no是varchar类型-- 致命陷阱2:左模糊查询
SELECT * FROM orders WHERE product_name LIKE '%手机%';-- 致命陷阱3:对索引列使用函数
SELECT * FROM orders WHERE DATE(create_time) = '2023-08-15';
避坑指南(划重点):
- 使用
EXPLAIN
查看执行计划时,重点看type
列(ALL全表扫描要警惕) - 字符串字段查询值必须加引号
- 联合索引注意最左前缀原则(比如index(a,b,c) 只查b,c用不上索引)
二、事务的"套娃"艺术
灵魂四连问:
- ACID特性分别怎么实现的?
- 事务隔离级别有哪些?(附赠连环追问)
- MVCC机制了解吗?
- 什么是幻读?怎么解决的?
隔离级别对照表(建议背下来):
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
READ UNCOMMITTED | ✔️ | ✔️ | ✔️ |
READ COMMITTED | ✖️ | ✔️ | ✔️ |
REPEATABLE READ | ✖️ | ✖️ | ✔️ |
SERIALIZABLE | ✖️ | ✖️ | ✖️ |
实战建议:
- MySQL默认使用RR级别但通过Next-Key Locking解决幻读
- 开发中慎用
SELECT ... FOR UPDATE
(容易引发死锁)
三、锁机制的相爱相杀
死亡问题:
“你说说乐观锁和悲观锁的区别?我们系统该用哪种?”
场景化解析:
- 库存扣减场景:版本号乐观锁(update set stock=stock-1, version=version+1 where version=当前版本)
- 财务记账场景:悲观锁(先select for update再操作)
锁的进化史:
- 表级锁(MyISAM的痛)
- 行级锁(InnoDB的救赎)
- 间隙锁(解决幻读的神器)
- 意向锁(提高锁检测效率)
四、存储引擎的抉择
必问题:“为什么InnoDB比MyISAM更适合现代应用?”
对比清单:
- 事务支持:InnoDB✅ vs MyISAM❌
- 崩溃恢复:InnoDB有redo log
- 并发性能:InnoDB行级锁 vs MyISAM表锁
- 全文索引:MyISAM✅(但5.6+版本InnoDB也支持了)
冷知识:
- 系统表空间文件
ibdata1
会像滚雪球一样增大(记得配置自动扩展)
五、慢查询的破案技巧
排查四部曲:
- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 单位秒
- 使用
mysqldumpslow
分析日志 - 用
SHOW PROCESSLIST
查看实时查询 - 性能分析神器:
pt-query-digest
六、分页的深度优化
经典问题:
“为什么LIMIT 100000,10这么慢?怎么优化?”
优化方案对比:
-- 原始写法(性能杀手)
SELECT * FROM orders LIMIT 100000,10;-- 优化方案1:子查询法
SELECT * FROM orders WHERE id >=
(SELECT id FROM orders ORDER BY id LIMIT 100000,1) LIMIT 10;-- 优化方案2:游标分页(适合连续翻页)
SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10;
七、高可用架构的基石
连环追问:
- 主从复制原理?
- 读写分离要注意什么?
- 怎么保证数据一致性?
复制原理图解:
主库binlog -> 从库IO线程 -> relay log -> SQL线程重放
避坑指南:
- 主从延迟问题(show slave status查看Seconds_Behind_Master)
- 半同步复制配置(等至少一个从库确认)
- GTID复制模式(5.6+版本推荐)
八、性能调优的终极武器
调优三板斧:
- 参数调优:
# 内存相关
innodb_buffer_pool_size = 机器内存的70%
sort_buffer_size = 2M
join_buffer_size = 2M# 日志相关
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
- SQL优化(重中之重!)
- 架构优化(分库分表、缓存策略等)
最后的大实话
每次面试到最后,面试官总会问:“你有什么问题要问我吗?”(超级重要!!!)这时候可以问:
- 咱们业务当前遇到的最大数据库挑战是什么?
- 现在数据库的QPS和主要瓶颈在哪里?
- 有没有遇到过分库分表的场景?
记住,MySQL面试就像医生问诊,要能快速定位问题,给出合理的解决方案。纸上得来终觉浅,建议大家在本地用Docker起个MySQL环境,把上述场景都实操一遍(真的会有新发现!)。最后祝大家面试时都能像操作EXPLAIN一样,把面试官的问题看得透透的!