mysql 5.7 中 innodb 全文索引通过内置 ngram 解析器首次实现中文生产可用,必须显式指定 with parser ngram 并配置 ngram_token_size 与 innodb_ft_min_token_size 一致,否则索引无法切分中文 token 导致 match 查不到结果。

INNODB 全文索引在 MySQL 5.7 中不是“单纯变快了”,而是解决了中文场景下根本不可用的问题——此前版本(如 5.6)的 INNODB 全文索引对中文基本失效,5.7 引入 ngram 解析器后,才真正具备生产可用性。
为什么必须显式指定 WITH PARSER ngram?
MySQL 默认全文解析器只认空格和标点分词,对连续中文字符串无感知。不加WITH PARSER ngram,建索引语句能成功,但 MATCH() AGAINST() 几乎查不到结果。
常见错误现象:MATCH(title) AGAINST('数据库') 返回空,而 LIKE '%数据库%' 能命中——说明索引存在,但没切出有效 token。
- 建索引时必须显式声明:CREATE FULLTEXT INDEX ft_title ON articles(title) WITH PARSER ngram
- MyISAM 表也支持 ngram,但只有 INNODB 能保证事务一致性、崩溃恢复和并发安全
- 如果已有索引,需先 DROP INDEX 再重建,不会自动升级
ngram_token_size 设为 1、2 还是 3?
这个值决定中文切分窗口大小,直接影响召回率与索引体积: -ngram_token_size = 1:切所有单字(“数据”→“数”、“据”),适合搜姓名、缩写,但倒排表膨胀严重,I/O 压力大
- ngram_token_size = 2(默认):切两字组合(“数据库”→“数据”、“据库”),覆盖多数常用词,平衡性最好
- ngram_token_size = 3:适合专业术语(如“关系型数据库”),但漏掉“数据”“库”等短词,召回下降
注意:该参数修改后必须重启 MySQL 才生效,且不会自动重建已有索引
innodb_ft_min_token_size 必须 ≤ ngram_token_size
这是最容易被忽略的致命配置。默认值是3,若你设了 ngram_token_size = 2 却没调低它,所有生成的二元词(如“数据”)都会被过滤掉。
必须在 my.cnf 中显式设置:
innodb_ft_min_token_size = 2
其他关键配套参数:
- innodb_optimize_fulltext_only = ON:否则 OPTIMIZE TABLE 不合并倒排索引碎片,长期运行后查询越来越慢
- innodb_ft_enable_stopword = OFF(可选):中文停用词表极简,关掉更可控;若要用自定义停用词,需提前创建 innodb_ft_user_stopword_table
- 表必须含 FTS_DOC_ID 字段:BIGINT UNSIGNED NOT NULL,且建议设为隐藏主键或自增列
真正让 MySQL 5.7 的 INNODB 全文索引“能用”的,不是某个单一参数调优,而是 ngram 解析器与事务引擎的深度绑定——它让中文搜索第一次在 ACID 保障下成为可能。但这也意味着,漏掉任意一个基础配置,它就退回“建了等于没建”的状态。











