InnoDB是绝大多数业务场景下的唯一合理选择,MyISAM仅适用于极少数静态只读、无崩溃恢复要求的归档表,且需承担数据损坏风险;其表级锁机制在高并发下易引发I/O等待飙升,而InnoDB凭借行锁+MVCC支持高并发读写,具备事务、外键及崩溃自动恢复能力,保障数据一致性与可靠性。

绝大多数业务场景下,InnoDB 是唯一合理选择;MyISAM 仅在极少数静态只读、无崩溃恢复要求的归档表中可考虑,且需主动承担数据损坏风险。
高并发写入或混合读写必须用 InnoDB
MyISAM 的表级锁机制会让一个 UPDATE 或 INSERT 阻塞整张表的所有后续读写,QPS 超过 10 就容易出现 Table_locks_waited 持续上升、iowait% 突破 40%。InnoDB 的行锁 + MVCC 能让不同行的读写并行,I/O 请求更分散,配合 innodb_io_capacity 可直接绑定 SSD 的 IOPS 能力。压测显示:当写入 QPS > 200 且含 UPDATE 时,MyISAM 的 I/O 等待时间常是 InnoDB 的 2–3 倍。
需要事务、外键或崩溃后自动恢复就别碰 MyISAM
订单创建+库存扣减+日志记录这类原子操作,一旦中间失败,MyISAM 无法回滚,数据必然不一致;服务器异常断电后,.MYD 和 .MYI 文件极易错位,触发 Incorrect key file for table 错误,强制 REPAIR TABLE 又会引发更大 I/O 风暴。InnoDB 的 redo log 和 undo log 是崩溃后自动前滚/回滚的基础设施,无需人工干预。
COUNT(*) 慢不是 InnoDB 的缺陷,而是事务一致性的代价
MyISAM 的 COUNT(*) 快,是因为它把行数缓存在内存里,但这个值在崩溃后不可信;InnoDB 每次都真实扫描已提交的行,结果始终准确。这不是性能问题,是设计取舍:
- 真要高频查总数?加个冗余字段(如
total_count),在事务里同步更新 - 近似值够用?查
information_schema.TABLES的TABLE_ROWS(误差可能达 40%) - 别在大表上直接跑
SELECT COUNT(*)——无论引擎,都是全表扫描
别依赖文档,用 SHOW ENGINES 和 SHOW TABLE STATUS 验证实际状态
有些旧部署里 InnoDB 被禁用,或因 innodb_buffer_pool_size 过小导致表现反常;建表语句没显式指定引擎时,MySQL 默认值也可能被改过。关键动作:
- 执行
SHOW ENGINES;确认InnoDB的Support是DEFAULT或YES - 执行
SHOW TABLE STATUS LIKE 'xxx';看当前表实际用的引擎,别信建表语句里没写的默认值 - 压测时重点看
Handler_read_rnd_next(全表扫描次数)和Innodb_row_lock_waits(行锁等待),比理论参数更有说服力
真正难判断的,往往不是“该选哪个引擎”,而是“这张表的访问模式是否真的符合你假设的读多写少”——业务逻辑变更、索引缺失、慢查询堆积,都可能让 MyISAM 的所谓优势瞬间反转成 I/O 雪崩点。



















