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 在事务、并发、恢复三方面都交不出生产环境要的确定性。除非你维护的是十年前的老系统且确认零写入,否则别碰它。
