MyISAM仅在完全静态、零写入、无任何事务/外键/崩溃恢复需求的极少数场景(如只读国家代码表)下可选;其余所有情况,包括定时INSERT、未来扩展可能,均必须用InnoDB。

MyISAM 在纯只读、无并发写入的场景下,SELECT 性能确实比 InnoDB 高 10%–30%,但这不等于“该选 MyISAM”。
关键判断是:只要业务存在哪怕一丁点写入(哪怕是定时任务 INSERT)、或未来可能加事务/外键/崩溃恢复需求,就必须用 InnoDB。
SELECT 快 ≠ 实际更快
-
MyISAM的读快,前提是:- 表完全静态(从不
INSERT/UPDATE) - 没有并发写操作(哪怕一个
INSERT都会触发表级锁,卡住所有后续查询) - 查询不走
WHERE条件或只走主键/索引字段(否则仍需全表扫描)
- 表完全静态(从不
-
InnoDB的读性能在合理配置下并不弱:-
innodb_buffer_pool_size占物理内存 50%–75% 时,热数据几乎全在内存 - 聚簇索引让主键查询极快,二级索引回表也只多一次指针跳转
-
COUNT(*)确实慢,但加WHERE条件后,两者差距大幅缩小甚至反转
-
常见错误现象:SHOW PROCESSLIST 中大量线程卡在 Waiting for table level lock —— 这说明你根本不是“只读”,只是没意识到那条 INSERT INTO log_table SELECT ... 定时任务正在锁死整张表。
MyISAM 的“快”背后全是隐性成本
-
REPAIR TABLE和OPTIMIZE TABLE会锁表,线上执行等于服务中断 - 崩溃后无法自动恢复,
myisamchk修复 TB 级表平均耗时 >30 分钟 - 不支持
FOREIGN KEY,关联逻辑得全靠应用层校验,出错概率陡增 -
TEXT/BLOB字段超 768 字节时,MyISAM仍存于数据文件中,拖慢全表扫描;而InnoDB会溢出到独立页,对主键查询影响更可控
真实压测案例:某新闻点击统计表原用 MyISAM,日均 INSERT 仅 200 条(来自定时归档),高峰期 SELECT QPS 降 40%;改用 InnoDB + 合理 buffer pool 后,QPS 反升 6 倍,且不再偶发超时。
什么情况下真能放心用 MyISAM
- 表内容完全静态,上线后永不变更(如国家编码表
country_codes) - 确认不会加任何外键、事务、备份一致性要求(例如 mysqldump --single-transaction 对
MyISAM无效) - 使用
myisampack压缩后只读加载,且能接受修复工具介入的运维风险 - 全文检索需求在 MySQL < 5.6 版本(新版
InnoDB已原生支持FULLTEXT)
注意:SELECT COUNT(<em>) FROM table</em> 在 MyISAM 中快,但这是个伪优化点——生产环境几乎没人真跑这个语句,更多是 COUNT() WHERE status=1,这时 InnoDB 配合索引反而更稳。
真正要盯住的不是“哪个引擎 SELECT 更快”,而是“你的‘只读’是不是被定时任务、后台脚本、误操作悄悄打破了”。一旦出现写入,MyISAM 的性能优势瞬间崩塌,且问题定位成本远高于提前选对引擎。


















