MySQL 5.6.4起InnoDB才真正支持全文索引,因此前版本缺失核心逻辑;需满足版本≥5.6.4、ENGINE=InnoDB、字段为VARCHAR/TEXT、显式创建FULLTEXT索引、用MATCH() AGAINST()查询,中文须启用ngram解析器。

InnoDB 在 MySQL 5.6 之后支持全文索引,不是功能“移植”,而是引擎自身完成了倒排索引机制的重构——它不再依赖 MyISAM 那套静态、锁表、无事务的索引模型,而是用一套与事务日志协同的异步合并架构重新实现。
为什么是 5.6.4 这个点?
MySQL 5.6.4 是 InnoDB 全文索引真正可用的分水岭。早于该版本的 5.6.x(比如 5.6.32)压根没实现核心逻辑,执行 ALTER TABLE ... ADD FULLTEXT 会静默失败或报错 ERROR 1214 (HY000): The handler doesn't support FULLTEXT indexes。这不是配置问题,是代码缺失。
InnoDB 全文索引怎么做到不破坏事务?
MyISAM 的全文索引更新是同步写磁盘、全表锁、不参与回滚;InnoDB 则把词项写入一组隐藏的辅助表(如 FTS_0000000000000123_0000000000000456_INDEX_1),所有变更先进缓存,再由后台线程异步合并到主索引。这意味着:
- INSERT/UPDATE 提交后,哪怕事务成功,新文本也可能几秒后才可被
MATCH() AGAINST()搜到 - 若中途崩溃,未合并的缓存会被丢弃,索引状态与数据始终一致
- 不会阻塞其他行的读写——但后台合并线程可能成瓶颈,需监控
INFORMATION_SCHEMA.INNODB_FT_CONFIG中的optimize_checkpoint
为什么建了索引却查不到结果?
常见失效不是因为“不支持”,而是踩中 InnoDB 的硬性门槛:
-
FULLTEXT只允许建在VARCHAR/TEXT列上,CHAR列会被忽略(SHOW INDEX里根本看不到该索引) - 默认最小词长是
3(@@innodb_ft_min_token_size),搜"go"或"a"直接过滤掉,不报错也不返回 - 停用词表默认开启,
"the"、"and"等词被跳过;改innodb_ft_server_stopword_table后必须重启 MySQL(MyISAM 也是),而 InnoDB 还支持运行时设空表 -
MATCH(title, content) AGAINST(...)里的字段顺序、数量、名字必须和FULLTEXT(title, content)定义完全一致,少一个、多一个、拼错名,就退化为全表扫描
中文搜索必须额外装 ngram 插件
MySQL 原生分词器按空格和标点切词,对中文无效。InnoDB 要支持中文,必须启用 ngram 解析器:
- 建表时加
WITH PARSER ngram:FULLTEXT(content) WITH PARSER ngram - 同时设
ngram_token_size=2(二元分词),否则默认按字切,效果差 -
ngram不是插件开关,是编译时内置,但必须显式声明,否则索引建了也白建
WITH PARSER ngram 或字段名错一位,MATCH 就永远返回空,连警告都没有。


















