InnoDB是事务型首选,MyISAM仅适用于纯读、全文检索等有限场景;二者在事务支持、锁机制、外键、索引结构和崩溃恢复上存在根本差异。

FULLTEXT 索引在 MyISAM 和 InnoDB 中都能用,但行为、限制和适用场景差异极大。如果你用的是 MySQL 5.6 及之后版本,且业务需要事务一致性或高并发写入,优先选 InnoDB;只有在明确需要 MyISAM 特有全文能力(如极低延迟的只读搜索、布尔模式下更宽松的停用词处理),才考虑 MyISAM。
MyISAM 的 FULLTEXT 索引为什么现在很少用了
MyISAM 的全文索引虽早于 InnoDB 支持,但它和引擎本身一样,存在硬伤:
- 不支持事务:插入/更新带全文索引的记录时,如果中途失败,索引可能残留脏数据,
REPAIR TABLE也未必能完全修复 - 表级锁:哪怕只是对一个字段做
INSERT,整个表被锁,全文索引更新期间其他查询会排队 - 停用词不可配置:默认停用词表固定(如 "the", "is"),无法增删,且对中文等语言基本无效
- 最小词长硬编码为 4:短词(如 "go", "AI")直接被忽略,
ft_min_word_len需重启 MySQL 才生效,线上几乎不可调 - 不支持地理空间 + 全文混合查询:MyISAM 虽支持空间函数,但无法和
MATCH ... AGAINST同时使用
InnoDB 的 FULLTEXT 索引从 5.6 起已足够可靠
MySQL 5.6 是分水岭——InnoDB 全文索引不再是“能用”,而是“可上线”。关键改进点包括:
- 支持事务原子性:
INSERT或UPDATE带全文字段时,索引更新与数据变更在同一事务中,崩溃后通过redo log一并恢复 - 无表级锁干扰:全文索引更新走内部 FTS(Full-Text Search)辅助表,不影响主表行锁,写入并发不受影响
- 停用词可自定义:可通过配置项
innodb_ft_server_stopword_table或建表时指定innodb_ft_user_stopword_table表来自定义 - 最小词长可调:
innodb_ft_min_token_size动态设置(需重建索引),支持中文分词场景下的 2 字词 - 支持自然语言、布尔、查询扩展三种模式,语法与 MyISAM 完全兼容,迁移成本极低
示例:创建带自定义停用词的 InnoDB 表
CREATETABLEarticles ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(200), body TEXT, FULLTEXT (title, body) ) ENGINE=InnoDB;
再执行:
SET GLOBAL innodb_ft_aux_table = 'test/articles';
即可触发索引同步(注意:该变量仅用于调试,生产环境靠自动后台线程)。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
哪些场景真该坚持用 MyISAM 的 FULLTEXT
极少,但确实存在。满足全部以下条件时才值得考虑:
- 表完全只读(如日志归档、静态百科词条),且数据量超大(>1TB),MyISAM 压缩表(
myisampack)能显著降低 I/O - 搜索请求极简单,且对停用词过滤非常敏感(例如必须搜到 "is not null" 中的 "is")
- MySQL 版本卡在 5.5 或更早,无法升级
- 已有大量 MyISAM 全文索引逻辑,且应用层深度依赖其统计行为(如
MATCH返回的相关度分数计算方式略有不同)
注意:SELECT COUNT(*) FROM myisam_table 快不是因为全文索引,而是 MyISAM 自带行数缓存——这和全文无关,别混淆。
容易被忽略的坑:全文索引重建和字符集
无论 MyISAM 还是 InnoDB,全文索引都严格依赖字符集和排序规则:
- 字段必须是
CHAR,VARCHAR,TEXT类型,且字符集不能是binary;utf8mb4完全支持,但utf8(即 utf8mb3)对某些 emoji 会截断,导致索引失效 - InnoDB 全文索引重建必须用
ALTER TABLE ... DROP INDEX ...; ALTER TABLE ... ADD FULLTEXT,不能只用OPTIMIZE TABLE(它只整理 B+Tree,不重建 FTS auxiliary tables) - MyISAM 表压缩后(
myisampack)变成只读,任何INSERT都报错The table is read only,全文索引也无法更新 - 全文索引不支持前缀索引:
FULLTEXT (title(10))语法非法,MyISAM 和 InnoDB 均不接受
最常踩的坑是:开发在测试库用 utf8 建了全文索引,上线后切到 utf8mb4 却没重建索引,结果中文搜索全返回空——因为索引还是按旧字符集解析的。










