结论:MyISAM 不适合并发压测,50 并发下失败率超 15%,InnoDB 通常低于 0.1%;其表级锁、无崩溃恢复、CHECK/REPAIR 锁表及缓冲配置敏感等问题,均使其在真实写读混合场景中显著劣于 InnoDB。

直接结论:别用 MyISAM 做并发压测,它在 50 并发下失败率就可能突破 15%,InnoDB 在同等条件下通常稳定在 0.1% 以内。
用 sysbench 跑 oltp_write_only 场景最能暴露差异
MyISAM 的表级锁在写入时会阻塞所有其他读写操作,而 InnoDB 的行级锁只锁涉及的行。真实业务中写操作常伴随读,所以单纯跑 select 得不到关键结论。
- 必须用
sysbench的oltp_write_only或oltp_read_write模式,不能只跑oltp_read_only - 并发数建议从 10、50、100 三级递增,观察平均响应时间(
avg latency)和失败率(failed requests)两个硬指标 - MyISAM 在 50 并发时经常出现
Lock wait timeout exceeded或连接超时,InnoDB 同样配置下基本不报这类错
MyISAM 的 CHECK TABLE 和 REPAIR TABLE 在压测中会雪上加霜
这些命令是表级操作,在高并发下会触发长时间锁表,导致压测结果严重失真——不是引擎慢,是被自己卡死的。
-
CHECK TABLE在 MyISAM 上会扫描整个 .MYI 文件并校验索引一致性,期间表不可写,读也可能被阻塞 -
REPAIR TABLE更危险:它先锁表,再重建 .MYI 和 .MYD,压测中途执行等于暂停所有请求 - InnoDB 的崩溃恢复由
innodb_force_recovery控制,且依赖 redo log 快速重放,不影响在线服务
缓冲池配置不当会让 InnoDB “看起来”比 MyISAM 还慢
InnoDB 性能严重依赖 innodb_buffer_pool_size,设太小会导致大量磁盘 I/O,掩盖其行锁优势。
- 默认值通常是 128MB,但一台 16GB 内存的服务器,设成 12GB 都不算激进
- 如果活跃数据集(比如热数据 8GB)远大于 buffer pool(比如只配了 2GB),
SHOW ENGINE INNODB STATUS里会出现Buffer pool hit rate 900/1000甚至更低的告警 - MyISAM 只缓存索引(
key_buffer_size),数据靠 OS page cache,所以压测时容易受系统内存压力干扰,结果波动大
纯读场景下 MyISAM 的 10%–30% 优势有严格前提
这个数字只在“无任何写入、索引完全命中、数据量不大、OS cache 充足”的理想条件下成立。现实业务几乎不存在这种环境。
- 一旦有
INSERT或UPDATE,哪怕每秒 1–2 次,MyISAM 表级锁就开始排队,后续查询延迟陡增 - MyISAM 不支持事务,
SELECT虽然不加锁,但若前面有未完成的写操作,读会等锁释放 - MyISAM 的
COUNT(*)快是因为它把行数存在 .MYI 文件头里,但这个值在并发写入时不准,需加WHERE条件时反而更慢
真正容易被忽略的是:MyISAM 没有崩溃恢复机制,突然断电或 kill -9 后,.MYD 和 .MYI 文件极易不一致,REPAIR TABLE 成功率随文件大小下降——而 InnoDB 的 redo/undo log 是原子写入的,只要磁盘没坏,重启就能回滚或重放。


















