
MyISAM 还能用吗?先看这三点
不能一概而论,但绝大多数新项目不该选 MyISAM。它不支持事务、行级锁、外键,崩溃后恢复能力弱——这些不是“可有可无”的特性,而是现代 Web 应用的底线要求。
如果你只是在本地跑一个只读的静态报表分析库,且表数据量小、更新极少,MyISAM 的 COUNT(*) 快、索引体积小确实有点优势;但只要涉及用户注册、订单提交、库存扣减这类操作,MyISAM 会直接让你掉进锁表、数据不一致、断电丢数据的坑里。
-
MyISAM表级锁:哪怕只更新一行,整张表都写不了 - 崩溃后靠
REPAIR TABLE恢复,成功率低,且无法保证数据逻辑一致 - 没有 MVCC,
SELECT和UPDATE在高并发下互相阻塞更严重
InnoDB 默认配置够用吗?关键参数必须调
MySQL 5.7+ 虽然默认引擎已是 InnoDB,但默认配置是为通用场景保守设计的,生产环境几乎一定需要调整。
最常被忽略的是 innodb_buffer_pool_size —— 它决定多少数据能缓存在内存里。设太小(比如默认 128MB),大量磁盘随机读拖垮性能;设太大(比如超过物理内存 70%),可能触发系统 OOM 杀进程。
- 线上建议值:
innodb_buffer_pool_size = 总内存 × 0.6–0.75(专用 DB 服务器) -
innodb_log_file_size影响 crash recovery 时间和写入吞吐:太小(如默认 48MB)导致频繁 checkpoint;太大(如 >2GB)会让崩溃后恢复变慢 -
innodb_flush_log_at_trx_commit = 1是 ACID 保障底线,别为了“快一点”改成 0 或 2——除非你明确接受断电丢最近 1 秒事务
什么时候真该考虑 MyISAM?别被“快”骗了
真实场景极少。所谓“MyISAM 更快”,基本只出现在两类测试里:单线程压测 SELECT COUNT(*),或者插入百万纯日志且从不更新的表。
但实际业务中,COUNT(*) 很少单独执行;而日志类数据现在更常用 ARCHIVE 引擎或直接上时序数据库(如 TimescaleDB)。另外,MyISAM 的“快”是建立在放弃一致性基础上的——它连 INSERT ... ON DUPLICATE KEY UPDATE 都不支持,更别说 REPLACE INTO 的原子性了。
- 全文索引曾是
MyISAM独占优势,但 MySQL 5.6+ 的InnoDB已完全支持 -
MyISAM的FULLTEXT不支持事务,搜索结果可能包含未提交的数据 - 如果真要极致读性能,优先考虑加缓存(Redis)、读写分离、物化视图,而不是降级引擎
迁移 MyISAM 到 InnoDB 会出什么错?
直接 ALTER TABLE t ENGINE=InnoDB 看似简单,但容易卡住、失败或产生隐性问题。
常见错误包括:ERROR 1071 (42000): Specified key was too long —— InnoDB 默认页大小 16KB,对 UTF8MB4 字段的索引长度限制比 MyISAM 更严;还有 auto_increment 列必须是索引的一部分,否则报错。
- 迁移前先检查:
SHOW CREATE TABLE t,确认主键/唯一键定义完整 - 长字符串字段(如
VARCHAR(1000))建索引前,显式指定前缀长度:INDEX idx_name (name(191)) - 大表迁移建议用
pt-online-schema-change,避免锁表;不要在业务高峰期执行ALTER - 迁移后务必验证:事务是否生效(
BEGIN; INSERT; ROLLBACK;后查是否回滚)、外键是否可用、查询执行计划是否变化
引擎不是开关,是底层数据组织方式的切换。改完引擎,不等于改完了逻辑一致性保障——那得靠代码里真正用好事务、锁和约束。











