InnoDB是业务场景下唯一合理的选择,MyISAM功能残缺、风险不可控,2026年已默认禁用;它不支持事务、崩溃恢复不可靠、表级锁严重制约并发,而InnoDB通过redo/undo log保障原子性与自动恢复。

InnoDB是绝大多数业务场景下唯一合理的选择,MyISAM不是“读快一点”的替代方案,而是功能残缺、风险不可控的遗留组件——它在2026年已默认禁用,且连REPAIR TABLE都可能丢数据。
事务一致性要求一出现,MyISAM就直接出局
只要你的业务涉及“多个操作必须全成功或全失败”,比如订单创建+库存扣减+日志记录,InnoDB就不是可选项,而是强制项。
- MyISAM对
BEGIN/COMMIT/ROLLBACK完全无视:语句一执行就落盘,中途崩溃 = 半截脏数据留在表里 - InnoDB依赖
redo log和undo log实现原子性:转账失败时,UPDATE自动回滚,余额不会只扣不转 - 批量导入(如
INSERT ... SELECT)中断后,MyISAM留下部分写入的损坏状态;InnoDB可回滚到事务起点,无需人工干预
高并发写入场景下,MyISAM的表级锁会成为系统瓶颈
UPDATE users SET status=1 WHERE id=123在InnoDB中只锁这一行;MyISAM则锁住整个users表,后续所有读写全部排队。
- 后台定时任务跑
INSERT INTO log_table,若表上有实时查询,MyISAM会卡住整个页面加载 - 并发稍高(>10 QPS 写入)时,
Table_locks_waited持续上升,监控上表现为响应延迟陡增 -
WHERE name LIKE "%admin%"因左模糊导致索引失效,InnoDB也会退化为全表扫描+行锁(不是表锁),但至少不阻塞其他无关行的更新
崩溃恢复不是“能不能修”,而是“要不要停服手动修”
服务器断电或进程异常退出后,InnoDB启动时自动重放redo log,秒级恢复;MyISAM需人工介入,且过程不可靠。
- MyISAM损坏后必须运行
REPAIR TABLE,该命令可能丢数据;更严重的损坏需停服使用myisamchk,期间表完全不可用 - InnoDB的崩溃恢复全自动,
ib_logfile0和undo logs共同保障一致性 - 主从复制环境下,MyISAM崩溃可能导致复制流中断,而InnoDB能保证GTID或binlog位置连续
别被COUNT(*)快慢误导,现实业务几乎从不执行无条件统计
MyISAM的COUNT(*)快,是因为它缓存了行数变量;但这结果不满足事务隔离语义,且带WHERE条件时两者都要走索引扫描。
-
SELECT COUNT(*) FROM orders WHERE status = 'paid':无论引擎,都需按索引过滤可见行,性能差异可忽略 - MyISAM的缓存值在并发写入时可能不准(尤其主从复制下),而InnoDB每次返回的是当前事务视角下真实可见的行数
- 真要高频查总数?加个冗余字段(如
total_count),在事务里同步更新;用近似值够用?查information_schema.TABLES里的TABLE_ROWS(误差可能达40%)
真正难判断的,往往不是“该选哪个引擎”,而是“这张表当前实际用的是哪个引擎”——执行SHOW TABLE STATUS LIKE 'xxx'确认,别信建表语句里没写的默认值;有些旧部署里MyISAM已被禁用,或InnoDB因innodb_buffer_pool_size过小表现反常。


















