本文是浓缩版速答。每题尽量一句话讲清结论;详细原理点对应链接。

一、索引

Q: 为什么 MySQL 用 B+ 树而不是 B 树/红黑树/Hash?
B+ 树非叶节点不存数据 → 一个节点能装更多 key → 树更矮 → 磁盘 IO 少;叶子节点链表 → 范围查询快。Hash 不支持范围、不支持排序。

Q: 聚簇索引 vs 二级索引?

  • 聚簇索引:叶子节点存整行数据,InnoDB 主键即聚簇索引
  • 二级索引:叶子节点存主键值,需要”回表”

Q: 什么是覆盖索引?详细
SELECT 的字段全在二级索引里,不用回表。EXPLAIN 显示 Using index

Q: 最左前缀原则?
联合索引 (a, b, c) 只能命中 a / a+b / a+b+c,不能 bb+c

Q: 索引为什么会失效?12 种原因
函数运算、隐式转换、%xxx、OR 含非索引列、违反最左前缀、负向查询…

Q: 什么时候不该建索引?优缺点
小表、低选择性字段、写多读少、字段经常更新。

二、事务与隔离级别

Q: ACID 是什么?

  • A 原子性:要么全做,要么全不做(undo log)
  • C 一致性:业务规则不被破坏(前 3 项的结果)
  • I 隔离性:并发事务相互不感知(锁 + MVCC)
  • D 持久性:提交后不丢(redo log)

Q: 4 种隔离级别?

级别脏读不可重复读幻读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ(InnoDB 默认)✓(间隙锁)
SERIALIZABLE

Q: MVCC 是什么?
多版本并发控制。每行有 trx_idroll_ptr,读时按 ReadView 找对自己可见的版本。实现 RC/RR 两种隔离级别下的非阻塞读

Q: 当前读 vs 快照读?

  • 快照读:普通 SELECT,走 MVCC 历史版本
  • 当前读:SELECT ... FOR UPDATE / LOCK IN SHARE MODE / 所有写操作,加锁读最新

三、锁

Q: InnoDB 锁类型?

说明
共享锁 S / 排他锁 X读锁 / 写锁
行锁锁单行
间隙锁 (Gap Lock)锁两行之间的”缝”,防幻读
临键锁 (Next-Key)行锁 + 间隙锁,RR 隔离级别默认加它
意向锁 IS/IX表级,标记”我打算在某行加 S/X 锁”

Q: 死锁怎么排查?

1
2
SHOW ENGINE INNODB STATUS;   -- 看 LATEST DETECTED DEADLOCK
SELECT * FROM performance_schema.data_locks;

Q: 死锁怎么避免?

  • 多个事务以相同顺序访问表/行
  • 事务保持短小
  • 低隔离级别(RC 不加间隙锁)
  • 给热点资源建索引(避免锁升级到表锁)

四、SQL 优化

Q: EXPLAIN 重点看哪几列?

  • type:访问类型,从好到差 system > const > eq_ref > ref > range > index > ALL
  • key:实际用到的索引
  • rows:预估扫描行数
  • ExtraUsing index(覆盖)/ Using filesort(额外排序,差)/ Using temporary(临时表,差)

Q: 慢 SQL 怎么排查?

  1. 开慢查询日志 slow_query_log = 1
  2. mysqldumpslow / pt-query-digest 聚合
  3. 单条 EXPLAIN / EXPLAIN ANALYZE
  4. SHOW PROFILE 看每阶段耗时

Q: LIMIT 100000, 20 怎么优化?
延迟关联:先用覆盖索引拿 20 个 id,再 join 主表。详见 覆盖索引

Q: COUNT(*) vs COUNT(1) vs COUNT(列)?

  • COUNT(*) / COUNT(1) 等价,统计行数(含 NULL)
  • COUNT(列) 不统计 NULL
  • InnoDB 都需要扫描,没有 MyISAM 那种缓存

五、存储引擎

Q: MyISAM vs InnoDB?

维度MyISAMInnoDB
事务
行锁✗(表锁)
外键
崩溃恢复强(redo log)
COUNT(*)缓存,O(1)需扫描
全文索引5.6+ ✓

结论:除非纯只读统计场景,永远用 InnoDB

六、主从复制 & 高可用

Q: 主从复制原理?

  1. 主库写入 binlog
  2. 从库 IO 线程拉取 binlog → 写 relay log
  3. 从库 SQL 线程回放 relay log

Q: 主从延迟怎么解决?

  • 大事务拆小
  • 从库开并行复制 (slave_parallel_workers)
  • 关键读走主库(”读己写”场景)
  • 上 ProxySQL / 中间件路由

Q: binlog 三种格式?

  • STATEMENT:记 SQL,体积小但函数/触发器主从结果可能不一致
  • ROW:记每行变化,安全推荐,体积大
  • MIXED:自动二选一

七、其它高频

Q: redo log 和 binlog 区别?

  • redo log:InnoDB 引擎层,物理日志(”在某页改某字节”),循环写
  • binlog:Server 层,逻辑日志,追加写,用于复制和恢复

Q: 一条 SQL 的执行流程?
连接器 → 查询缓存(8.0 移除)→ 分析器(词法/语法)→ 优化器(选索引、决定 join 顺序)→ 执行器 → 存储引擎

Q: 表设计三范式?
1NF:字段不可再分;2NF:非主键完全依赖主键;3NF:非主键不传递依赖。实际开发常反范式(冗余字段)换性能

配图

索引执行流程

索引常见面试问题脑图

进一步阅读