MyISAM 仅适用于几乎无更新、纯读场景,如静态配置表、日志归档表;不支持事务、行级锁和崩溃安全恢复,高并发或需一致性的业务必须用 InnoDB。

MyISAM 适合什么场景?直接看读写比例和事务需求
MyISAM 只适合「几乎不更新、纯查得多」的表,比如静态配置表、日志归档表(只 INSERT 一次,之后只 SELECT)、博客文章列表页缓存表。一旦业务里有 UPDATE 或 DELETE 频繁操作,或者需要 BEGIN/COMMIT 保证一致性(比如下单扣库存),就必须换 InnoDB —— MyISAM 不支持事务,出错就回不了头。
- 典型误用:用 MyISAM 存用户订单表,结果支付回调时网络中断,
INSERT成功但状态没更新,数据逻辑错乱且无法回滚 - 能用的前提:确认应用层已自行处理并发冲突(比如用 Redis 分布式锁),且能接受断电后手动
REPAIR TABLE - 注意:MySQL 8.0 已移除 MyISAM 的全文索引优势,InnoDB 的
FULLTEXT索引功能已完全对标,无需为全文搜索迁就 MyISAM
为什么 COUNT(*) 在 MyISAM 里快,但线上千万别信它?
MyISAM 会把总行数存在磁盘元数据里,所以 SELECT COUNT(*) FROM t 是 O(1) 查表头,秒出结果;而 InnoDB 要扫描索引或采样估算,慢得多。但这只是“表面快”——实际线上环境,这个值极可能不准。
- 原因:MyISAM 的行数统计不加锁,
INSERT和COUNT(*)并发时会脏读计数器,返回过期值 - 更糟的是:如果表被
OPTIMIZE TABLE或崩溃修复过,计数器可能重置为 0,后续COUNT(*)直接全表扫 - 真实建议:宁可用 InnoDB + 覆盖索引(如
SELECT COUNT(id) FROM t WHERE id > 0)或加缓存,也别依赖 MyISAM 的“快”
表级锁怎么拖垮高并发?一个 UPDATE 就让所有查询排队
MyISAM 写操作(INSERT/UPDATE/DELETE)会锁整张表,期间所有读请求(哪怕查的是不同行)都得等。这不是理论瓶颈,是真实压测中 QPS 断崖下跌的根源。
- 现象举例:后台定时任务跑
UPDATE t SET status=1 WHERE day='2026-01-28',持续 3 秒 → 这 3 秒内所有前端SELECT * FROM t WHERE id=123全部阻塞 - 对比 InnoDB:同样语句只锁匹配的几行,其他行照常读写,MVCC 还能让读不加锁
- 排查方法:执行
SHOW OPEN TABLES WHERE In_use > 0,看到某张 MyISAM 表In_use值长期 > 1,基本就是锁争用信号
崩溃后恢复有多痛苦?别等出事才试
MyISAM 没 redo log,崩溃后数据文件(.MYD)和索引文件(.MYI)极易不一致。轻则 SELECT 报错 Incorrect key file for table,重则整个表不可读。
- 恢复流程:必须停服务 → 手动运行
myisamchk -r t.MYI→ 修复失败就得从备份拉,期间服务中断 - 而 InnoDB 崩溃重启后自动前滚(redo)+ 回滚(undo),通常 10 秒内完成恢复,业务无感
- 隐藏风险:MyISAM 的
REPAIR TABLE可能静默丢数据(比如跳过损坏块),但不会报错,你根本不知道丢了哪几条
现在 MySQL 默认引擎是 InnoDB,不是因为“新”,而是因为 MyISAM 在事务、并发、恢复三方面都交不出生产环境要的确定性。除非你维护的是十年前的老系统且确认零写入,否则别碰它。










