InnoDB 存储结构
默认引擎 InnoDB,支持事务、行级锁、外键(少用)。数据按 B+ 树聚簇索引 组织:叶子节点存完整行,非叶子存主键路由。表若无主键会选唯一非空列或隐式 row_id。
二级索引叶子存主键值,查询需回表;覆盖索引(索引含查询列)可避免回表。
-- 联合索引 (a, b, c) 最左前缀:可用 a; a,b; a,b,c
EXPLAIN SELECT id, b FROM t WHERE a = 1 AND b = 2;
-- Extra: Using index 表示覆盖索引
事务 ACID 与隔离级别
| 级别 | 脏读 | 不可重复读 | 幻读 | |---|---|---|---| | READ UNCOMMITTED | 可能 | 可能 | 可能 | | READ COMMITTED | 否 | 可能 | 可能 | | REPEATABLE READ | 否 | 否* | InnoDB 大体防 | | SERIALIZABLE | 否 | 否 | 否 |
*RC 下每次 SELECT 新快照;RR 下同一事务 Read View 不变。
MVCC:undo log 版本链 + Read View;快照读 普通 SELECT 无锁;当前读 SELECT ... FOR UPDATE、UPDATE/DELETE 加锁。
锁类型
- Record Lock:记录上的锁。
- Gap Lock:间隙,防插入幻读。
- Next-Key Lock:Record + Gap,RR 默认。
日志体系
- redo log:WAL,Page 物理修改,循环写,崩溃恢复。
- undo log:回滚与 MVCC 历史版本。
- binlog:逻辑日志,主从、备份;与 redo 两阶段提交(prepare → commit)保证一致性。
innodb_flush_log_at_trx_commit=1 每次提交刷 redo,最安全;=2 写 OS 缓存,依赖 fsync。
优化与实践
- 建索引看 WHERE / ORDER / JOIN 列,避免函数破坏索引。
- 长事务阻塞 undo 清理,导致表膨胀。
- 大分页用
WHERE id > last_id LIMIT n替代深OFFSET。 - 执行计划关注
type、key、rows、Extra(Using filesort/temporary 警惕)。
延伸阅读
站内专题 MySQL 面试章节 有更系统的刷题路线、手写 SQL 与场景题拆解,建议与本篇索引/事务/日志三角对照复习。
面试答题路径:场景(慢查询/死锁)→ 原理(索引/锁/MVCC)→ 手段(EXPLAIN、改 SQL、拆库表)→ 风险(主从延迟、锁等待),体现完整工程思维。