MySQL 5.5起默认引擎改为InnoDB,因其具备事务一致性、高并发行锁及崩溃自动恢复能力,而MyISAM无redo/undo日志、表级锁且修复不保数据完整,已无法满足现代业务底线要求。

为什么 MySQL 5.5 之后默认引擎变成 InnoDB
因为 MyISAM 在崩溃后无法自动恢复,而现代业务根本不敢用一个写坏就可能丢数据、还要手动 REPAIR TABLE 的引擎。InnoDB 是唯一能同时扛住「事务一致性」、「高并发写入」和「异常宕机自愈」三重压力的默认选项。
这不是偏好问题,是底线问题:只要你的应用有用户注册、订单提交、库存变更,就必须用 InnoDB。
- MyISAM 没有
redo log和undo log,断电或 kill -9 后,.MYD文件极大概率损坏,且修复不保证数据完整 - InnoDB 崩溃重启时自动执行
crash recovery,靠日志重做已提交事务、回滚未提交事务,几分钟内回到一致状态 - MySQL 官方从 5.5 开始将
innodb设为默认,不是为了“先进”,而是因为myisam已经没法在线上活了
MyISAM 表级锁在并发写入时到底多卡
一条 UPDATE users SET status=1 WHERE id=1005,MyISAM 会锁整张 users 表;InnoDB 只锁 id=1005 这一行——前提是 id 是主键或有索引。这是两者并发能力鸿沟的起点。
- MyISAM 写操作期间,所有其他写请求排队,读请求也被阻塞(除非加
LOW_PRIORITY) - InnoDB 行锁 + MVCC 让“1000 人抢同一商品”只争抢那一行库存,查订单、改地址、浏览列表全都不受影响
- 但注意:
WHERE条件没走索引(比如WHERE name LIKE '%abc'),InnoDB 也会退化为锁表,所以索引设计不能偷懒
InnoDB 聚簇索引对查询性能的真实影响
主键就是数据本身的位置。InnoDB 表里,SELECT * FROM users WHERE id=123 通常一次磁盘 I/O 就拿到全部字段;而 MyISAM 需要先查索引得地址,再按地址去读数据文件,至少两次 I/O。
- 这意味着:没有显式定义主键的 InnoDB 表,MySQL 会悄悄生成一个隐藏的
row_id当聚簇键,这会让二级索引变大、写入变慢 - 建议始终用
BIGINT UNSIGNED AUTO_INCREMENT或UUID(带时间前缀)作主键,避免用长字符串或复合主键 - 二级索引(比如
INDEX idx_email ON users(email))实际存的是email + 主键值,所以主键越短,索引越省空间
MyISAM 还值得选吗?哪些场景真能用
几乎不推荐。仅当满足全部三个条件时,才考虑 MyISAM:纯静态内容、几乎零更新、需要高频 COUNT(*) 或老版本全文检索。
-
COUNT(*)快是因为 MyISAM 在内存里缓存了精确行数;InnoDB 每次都扫索引,大数据量下明显慢——但这不是选 MyISAM 的理由,而是该用缓存或异步统计 - MyISAM 的全文索引在 MySQL 5.6 之前是独占优势,但现在 InnoDB 已支持,只是对中文分词仍弱于 Elasticsearch
- 嵌入式设备或内存极度受限环境可能倾向 MyISAM(它没
buffer_pool开销),但这类场景现在更常直接用 SQLite
真正容易被忽略的点是:哪怕你只读不写,只要数据库要升级、备份、主从同步,InnoDB 的一致性保障和工具链支持都远超 MyISAM。别为省几毫秒 COUNT 换掉整个数据安全底座。


















