MySQL 默认用
InnoDB,绝大多数业务场景直接选它就对了;只有明确需要全文索引+高并发读、或极低延迟的只读归档场景,才考虑
MyISAM或
Archive——但后者几乎不用在主业务表中。
为什么 InnoDB
是默认且首选
InnoDB支持事务、行级锁、外键、崩溃恢复,这些不是“锦上添花”,而是现代 Web 应用数据一致性的底线。比如一个转账操作涉及两条
UPDATE,若用
MyISAM,中途失败会导致数据不一致,且无法回滚。 写多或读写混合场景下,
InnoDB的行锁比
MyISAM的表锁吞吐高得多
InnoDB的 MVCC 机制让普通
SELECT不加锁,读性能不因写阻塞 即使你暂时没用事务,也建议开启(
autocommit=1是默认),为后续扩展留余地
InnoDB表空间可在线收缩(
ALTER TABLE ... ROW_FORMAT=COMPACT配合
OPTIMIZE TABLE),
MyISAM的
.MYD文件一旦膨胀很难回收
MyISAM
仅剩的适用场景和风险
MyISAM现在基本只用于:历史日志表(如用户点击流)、报表宽表(纯
SELECT+
FULLTEXT搜索)、或遗留系统迁移过渡。但它不支持事务,
INSERT过程中整表锁定,且崩溃后需手动
REPAIR TABLE。 如果真要用
MyISAM,务必关闭
delay_key_write(默认 ON),否则断电可能丢索引数据
MyISAM的
COUNT(*)虽快,但结果不准(不加
WHERE时依赖表头缓存,非实时统计) 5.7+ 版本已移除
MyISAM全文索引的布尔模式部分功能,
InnoDB的
FULLTEXT已足够覆盖
别碰 Memory
引擎,除非你清楚后果
Memory引擎把表存在 RAM 里,重启即空——它不是缓存方案,而是临时计算容器。常见误用是拿它存“热点配置”或“会话信息”,结果服务重启后全丢。 只适合生命周期明确的中间结果,例如
CREATE TEMPORARY TABLE t ENGINE=MEMORY SELECT ...不支持
TEXT/
BLOB类型,
VARCHAR实际按
CHAR存储,内存浪费严重 所有连接共用同一份内存池(
max_heap_table_size),一张大表可能挤爆其他查询
架构设计时真正该关注的引擎之外的事
比起纠结引擎,更关键的是:字段类型是否精简(比如用
TINYINT代替
INT存状态)、索引是否覆盖高频
WHERE条件、是否避免
SELECT *、分库分表时机是否合理。引擎只是底座,上面的数据访问模式才决定性能上限。
一个容易被忽略的点:
InnoDB的聚簇索引特性意味着主键选择直接影响所有二级索引大小——如果用 UUID 做主键,每个二级索引的叶子节点都要存完整 16 字节 UUID,而自增
BIGINT只要 8 字节,长期看 IO 和内存开销差异明显。
