mysql MyISAM存储引擎有什么特点_mysql引擎区别说明

来源:这里教程网 时间:2026-02-28 20:45:24 作者:

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

相关推荐