应优先选InnoDB:因MyISAM不支持事务、行锁、外键及崩溃恢复,sysbench oltp_read_write会失败,仅oltp_point_select可运行但无参考价值;真实OLTP场景必须用InnoDB。

怎么选InnoDB还是MyISAM做基准测试?先看业务是否支持事务
MyISAM不支持事务、行锁、外键,也不支持崩溃恢复——这意味着只要测试里出现 COMMIT、ROLLBACK 或者 SELECT ... FOR UPDATE,它就直接报错或行为异常。Sysbench 的 oltp_read_write 脚本默认带事务,用 MyISAM 运行会失败;而 oltp_point_select(只读)勉强能跑,但结果毫无参考价值:它掩盖了写入瓶颈,也测不出并发更新时的锁争用。
- 真实 OLTP 场景(电商、订单、账户)必须用
InnoDB,别在 MyISAM 上浪费时间跑“高 TPS”假数据 - MyISAM 仅适合极少数场景:静态报表库、日志归档表、纯读+全表扫描+低并发,且你明确接受单点写入阻塞和宕机丢数据风险
-
SHOW ENGINES;确认支持状态,Percona Server 或 MySQL 8.0+ 默认已禁用 MyISAM,SUPPORT=NO就别试了
sysbench 测试命令里哪些参数会让 InnoDB 和 MyISAM 结果完全不可比?
很多人直接套用同一套 sysbench --test=oltp_read_write 命令对比两个引擎,但忽略关键配置差异:InnoDB 严重依赖 innodb_buffer_pool_size,而 MyISAM 几乎不走 buffer pool,只靠 OS page cache;MyISAM 的 key_buffer_size 只缓存索引,数据页全靠磁盘随机读。
- 必须分别调优:InnoDB 测试前设
innodb_buffer_pool_size = 70% RAM;MyISAM 则需加大key_buffer_size并确保read_buffer_size足够,否则 IO 成瓶颈主因 -
--oltp-table-size设太大(如 1000 万行),MyISAM 的REPAIR TABLE和OPTIMIZE TABLE会卡死,InnoDB 却能在线 DDL - MyISAM 不支持
--mysql-storage-engine参数自动建表,建表语句得手写ENGINE=MyISAM,否则 sysbench prepare 默认建 InnoDB 表
响应时间抖动大、TPS 波动剧烈?大概率是 MyISAM 表级锁在拖后腿
跑 sysbench --threads=32 run 时,InnoDB 通常呈现平滑的 QPS 曲线,而 MyISAM 往往在 5–10 秒内反复跌零——这不是机器问题,是写操作(INSERT/UPDATE)触发整表锁,所有其他线程排队等待。
- 用
SHOW PROCESSLIST;观察,能看到大量Locked状态的UPDATE或INSERT线程 - MyISAM 的
concurrent_insert=2只缓解“尾部插入”并发,对主键更新、非空字段修改无效 - 即使只读测试,如果
--oltp-read-only=on没加对,sysbench 仍可能混入写语句,MyISAM 一写就卡
为什么 MyISAM 在 SSD 上的基准测试结果反而比 HDD 差?
这不是硬件问题,是 MyISAM 的索引结构缺陷:它的 B-Tree 索引节点不压缩,且无预读机制,在高并发随机读下,SSD 的低延迟放大了锁竞争和 CPU 解析开销;而 HDD 的天然高延迟反而“掩盖”了部分争用,曲线看起来更稳。
- MyISAM 的
myisam_sort_buffer_size影响LOAD DATA INFILE速度,但对运行时查询无优化作用 - 对比测试务必关闭
query_cache_type(MySQL 5.7+ 已废弃),否则 MyISAM 查询缓存命中率虚高,InnoDB 完全不走该路径 - MyISAM 的
DATA DIRECTORY和INDEX DIRECTORY分离存储对性能无实质提升,反而增加运维复杂度
INSERT ... SELECT 或子查询更新,MyISAM 的结果连可重复性都难保证。



















