innodb是mysql 5.5+默认且8.0系统表强制使用的事务型引擎,支持行锁、mvcc、崩溃恢复和外键;myisam为已淘汰的非事务引擎,仅表锁、无崩溃恢复,仅作兼容。

InnoDB 是当前 MySQL 生产环境的绝对主力,MyISAM 已在 MySQL 8.0 中被系统表完全弃用,仅保留向后兼容;如果你还在为“选哪个”纠结,大概率是踩在过时经验或模糊认知上——真正要搞懂的不是“区别列表”,而是「哪些行为由引擎决定,且不通过 SQL 语法体现」。
为什么 SELECT COUNT(*) 在 MyISAM 快、InnoDB 慢
MyISAM 在内存中维护一个实时行数计数器,SELECT COUNT(*) 直接返回该值,不扫描数据文件。InnoDB 没有全局行数缓存,因为 MVCC 下不同事务看到的“可见行数”可能不同,它必须按隔离级别实际遍历(哪怕只是索引树),所以默认会走索引扫描甚至全表扫描。
- 加
WHERE条件后两者行为一致:都得查数据,MyISAM 也不再走计数器 - InnoDB 的
COUNT(*)性能取决于是否能走覆盖索引;如果主键是自增且无删除,有些 DBA 会建SELECT MAX(id)估算,但不精确 - MySQL 8.0+ 对
INFORMATION_SCHEMA.TABLES中的TABLE_ROWS字段做了优化,但仍是估算值,不可用于业务逻辑
UPDATE 或 DELETE 语句锁住整张表?先看引擎
MyISAM 对所有写操作使用表级锁:UPDATE t SET a=1 WHERE b=2 会锁整个表,期间其他写请求全部排队;InnoDB 默认行级锁,但「行级」不等于「只锁匹配行」——如果 MySQL 无法确定扫描范围(例如没走索引、用 LIKE '%abc'、或者索引失效),InnoDB 会升级为锁全表(lock escalation)。
- 检查执行计划:
EXPLAIN看type是否为ALL或index,这类扫描容易触发全表锁 - MyISAM 的表锁不可被中断,一旦阻塞,只能等前一个写完成;InnoDB 支持锁等待超时(
innodb_lock_wait_timeout),可主动失败 - 即使 InnoDB 走了索引,若更新涉及二级索引和聚簇索引分离修改(如更新非主键字段且有多个二级索引),仍可能产生额外锁竞争
崩溃后数据还在不在?引擎说了算,不是配置说了算
MyISAM 没有崩溃恢复机制:进程异常退出后,.MYD 文件可能处于中间状态,需手动运行 myisamchk 修复,且无法保证事务原子性。InnoDB 依赖 redo log 和 undo log 实现崩溃可恢复——只要 innodb_flush_log_at_trx_commit=1(默认),提交的事务就一定能重放;未提交事务则通过 undo log 回滚。
-
innodb_flush_log_at_trx_commit=0或2会提升写性能,但牺牲部分持久性:前者每秒刷一次日志,后者每次提交只写 OS 缓冲区,机器断电可能丢 1 秒数据 - MyISAM 的
REPAIR TABLE不是回滚,而是尝试重建索引并跳过损坏行,数据完整性无保障 - MySQL 8.0 系统库(
mysqlschema)已全部强制使用 InnoDB,mysqld --initialize初始化时不再生成 MyISAM 系统表
外键、MVCC、全文索引——别默认它们都可用
MyISAM 完全不支持外键和 MVCC;InnoDB 从 5.6 开始支持全文索引,但语法和分词逻辑与 MyISAM 不同(例如不支持布尔模式中的 +/- 前缀,需用 IN NATURAL LANGUAGE MODE 或 IN BOOLEAN MODE 显式声明)。
- 外键约束只在 DML 时生效(
INSERT/UPDATE/DELETE),ALTER TABLE ... ENGINE=InnoDB不会自动校验历史数据一致性 - MVCC 不是“免费午餐”:InnoDB 的
READ COMMITTED和REPEATABLE READ隔离级别下,长事务会拖慢 purge 线程清理undo log,导致ibdata1文件持续膨胀 - MyISAM 的全文索引对中文支持极差(按空格切词),InnoDB 的
ngram插件虽支持中文分词,但需额外配置innodb_ft_parser,且不兼容所有字符集
真正卡住人的从来不是“哪个更快”,而是「为什么看起来一样的 SQL,在不同引擎下行为完全不同」——比如 SELECT 不加 FOR UPDATE 时,MyISAM 读不加锁,InnoDB 在 REPEATABLE READ 下仍要构建一致性视图;这些差异藏在引擎实现里,不看执行计划、不查 SHOW ENGINE INNODB STATUS、不理解锁监控输出,光靠背区别表永远绕不出坑。











