绝大多数新项目应选InnoDB,因其支持事务、行级锁、外键和崩溃恢复;MyISAM仅适用于纯读、静态字典表等极少数场景;Memory适合临时表或小码表;Archive适合一次写入、极少查询的归档日志。

MyISAM 和 InnoDB 到底该选谁
绝大多数新项目直接选 InnoDB 就对了。它支持事务、行级锁、外键、崩溃恢复,MySQL 5.5+ 默认引擎就是它。只有极少数场景才考虑 MyISAM:比如纯读、全文索引(5.6+ 的 InnoDB 已支持)、或者历史遗留的静态数据表(如地区字典表),且确定永不更新。
常见错误是“听说 MyISAM 快就全用它”,结果一上并发写就卡死——MyISAM 是表级锁,INSERT 或 UPDATE 会锁整张表。
- 高并发读写、需要事务(如订单、账户)→ 必选
InnoDB - 只读大表、历史归档、磁盘空间极度敏感 → 可评估
MyISAM,但优先考虑InnoDB+read_only=1+ 压缩表 - 全文检索需求 → MySQL 5.6+ 直接用
InnoDB的FULLTEXT索引,不用切引擎
什么时候该考虑 Memory 引擎
Memory 引擎把数据存在内存里,查得快,但服务重启就丢数据,也不支持 BLOB/TEXT。它不是用来替代 InnoDB 的,而是做临时中间结果或缓存映射表。
典型误用:把用户会话表设成 Memory。一旦 MySQL 挂了,所有登录态丢失,还无法回滚恢复。
- 临时汇总统计(如报表预计算中间表)→
CREATE TEMPORARY TABLE ... ENGINE=MEMORY - 小规模、高频查询的码表(如状态码映射),且能接受重启后重新加载 → 可用,但建议配合初始化脚本
- 需要持久化、要事务、有大字段 → 绝对别用
Memory - 注意
max_heap_table_size参数限制单表大小,默认 16MB,超限会报错ERROR 1114 (HY000): The table 'xxx' is full
Archive 引擎适合什么冷数据场景
Archive 是为归档设计的:只支持 INSERT 和 SELECT,行压缩率高,适合存日志、审计、操作记录等“写了就再也不改”的数据。但它不支持索引(除主键外),SELECT 全表扫描,查单条很慢。
有人把它当“廉价存储”塞进大量低频访问数据,结果运维时发现查一条半年前的操作记录要 20 秒——因为没索引,又没法加。
- 符合“一次写入、极少查询、按时间范围批量导出”的日志类数据 → 合适
- 需要按用户 ID 或时间点快速定位某条记录 → 不合适,改用
InnoDB分区表 + 归档策略 - 想节省磁盘?先确认是否真比
zlib压缩的InnoDB表更省——实测中,开启ROW_FORMAT=COMPRESSED的InnoDB表压缩率接近Archive,且可索引、可事务
别忽略引擎切换的隐性代价
用 ALTER TABLE t ENGINE=InnoDB 切换引擎,看起来一行命令,实际是重建整张表:锁表、拷贝数据、重建索引。千万级表可能耗时几十分钟,期间写操作全部阻塞。
更隐蔽的问题是字符集和排序规则继承:从 MyISAM 切到 InnoDB,如果原表用了 utf8mb4_unicode_ci,但实例默认是 utf8mb4_0900_as_cs,切换后可能触发隐式转换,导致索引失效或查询变慢。
- 大表切换前,务必在从库或测试环境跑通,观察
SHOW PROCESSLIST中的copy to tmp table阶段耗时 - 显式指定字符集和排序规则:
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs ENGINE=InnoDB - 线上大表迁移,优先用
pt-online-schema-change或 MySQL 8.0+ 的原子 DDL,避免长锁
引擎不是选完就一劳永逸的配置项;它牵扯锁行为、崩溃恢复逻辑、备份一致性、甚至主从复制格式(STATEMENT vs ROW)。真正容易被跳过的,是上线前用真实负载压测不同引擎下的锁等待和 QPS 波动。










