MySQL 存储引擎
InnoDB 为什么是默认选择
从 MySQL 5.5 起,InnoDB 就是默认存储引擎,也是业务表几乎唯一需要认真对待的引擎。它同时提供事务、行级锁、MVCC、崩溃恢复和外键,写并发和宕机恢复都建立在 redo / undo 之上。
MyISAM 曾是 5.1 之前的默认引擎,只有表级锁、没有事务,崩溃后修复能力弱。现在偶尔还能在只读统计、某些临时结果里见到,生产业务表已经没有再选它的理由。
「InnoDB 查询一定比 MyISAM 慢」是过时结论。当前版本里 InnoDB 读路径并不弱,Buffer Pool 可以把热点页留在内存;真正拉开差距的是并发更新和崩溃恢复,这两项 MyISAM 补不上。
InnoDB 与 MyISAM 对比
| 特性 | InnoDB | MyISAM |
|---|---|---|
| 事务 | 支持 | 不支持 |
| 行级锁 | 支持 | 主要是表级锁 |
| MVCC | 支持 | 不支持 |
| 崩溃恢复 | redo + undo | 能力较弱 |
| 外键 | 支持 | 不支持 |
| 并发更新 | 高 | 低 |
| 索引形态 | 聚簇索引,主键叶子节点存整行 | 非聚簇索引,叶子节点存行地址 |
| 文件 | MySQL 8.0 每表一个 .ibd(数据 + 索引) | .MYD 数据 + .MYI 索引 |
| 使用场景 | 业务系统、需要事务和并发写 | 读多、对事务要求低;现在很少用 |
InnoDB 的表数据按主键顺序排在聚簇索引里。主键选得乱,插入就会在页中间打洞,引发页分裂。MyISAM 数据和索引分开,主键和二级索引都只存行指针,这一点和 InnoDB 的二级索引「叶子存主键、再回表」不一样。
Buffer Pool 与其他引擎
InnoDB 把数据页、索引页缓存在 Buffer Pool 里,改动先写内存和 redo,再择机刷盘。Change Buffer 用来合并二级索引的写,自适应哈希索引则是引擎在 Buffer Pool 里自动建的等值加速结构,不能当成「给 InnoDB 表手写 HASH 索引」。
MEMORY 引擎整表放内存,适合生命周期很短的中间结果,进程退出或宕机数据就没了。磁盘临时表在 MySQL 8.0 里也不再依赖 MyISAM,而是 TempTable / InnoDB。
选引擎时默认 InnoDB 即可。为了「读更快」把业务表改成 MyISAM,会同时丢掉事务、行锁和可靠恢复,这个交换现在不成立。