MySQL全文索引停用词默认由内置表提供,ft_stopword_file不生效主因是未重启mysqld、未重建索引或路径/权限/编码错误;中文需配合ngram解析器才生效。

MySQL 全文索引默认停用词在哪?ft_stopword_file 不生效的常见原因
MySQL 5.7+ 默认启用内置停用词表(如 “the”、“is”、“in” 等常见英文词),你改了 ft_stopword_file 却没效果,大概率是因为:没重启 mysqld、没重建全文索引、或者路径权限不对。
-
ft_stopword_file是只读变量,修改后必须重启 MySQL 实例才生效(不是FLUSH TABLES或SET GLOBAL能触发的) - 已有表的全文索引不会自动更新停用词逻辑——必须
ALTER TABLE ... DROP INDEX再ADD FULLTEXT - 文件路径必须是绝对路径,且 MySQL 进程用户(如
mysql)要有读取权限;Windows 下反斜杠要写成双反斜杠或正斜杠 - 文件格式必须是纯文本,每行一个词,不能有空行、BOM、注释或多余空格;MySQL 8.0 开始还要求 UTF-8 编码(无 BOM)
怎么自定义停用词文件并让全文索引真正用上它
别碰系统内置停用词表,直接配自己的文件最稳妥。关键是三步闭环:写对文件 → 配对参数 → 重建索引。
- 新建停用词文件,比如
/etc/mysql/custom_stopwords.txt,内容示例:apple banana test
- 在
my.cnf的[mysqld]段落加一行:ft_stopword_file = /etc/mysql/custom_stopwords.txt - 重启 MySQL:
sudo systemctl restart mysql(确认日志里没有 “Could not open stopword file” 报错) - 对目标表执行:
ALTER TABLE articles DROP INDEX ft_title_body; ALTER TABLE articles ADD FULLTEXT(title, body);
中文全文索引为啥停用词不管用?根本就不是停用词的问题
MySQL 原生 MATCH ... AGAINST 对中文支持极弱——它按空格/标点切词,不支持中文分词。你加了一堆中文词到停用词表,但引擎压根没把它们当“词”来处理,自然不进也不出停用逻辑。
- 现象:插入含 “的”、“了”、“和” 的中文数据,
MATCH仍返回结果,改ft_stopword_file无效 - 原因:MySQL 5.7/8.0 的全文索引不识别中文语义,所谓“停用”前提是先能正确切出中文词,而它不能
- 替代方案:用
ngram解析器(MySQL 5.7.6+),设置ft_parser = ngram并调ngram_token_size(常用 2),此时停用词才对 ngram 切出的二元组起作用 - 注意:
ngram下停用词匹配的是切片(如 “中国”、“国人”),不是原词;且ft_stopword_file仍需重启 + 重建索引
ft_min_word_len 和 ft_max_word_len 怎么配合停用词一起用
这两个参数决定哪些“词”会被存入全文索引,直接影响停用词是否有机会被检查。它们和 ft_stopword_file 是协同过滤关系,不是互斥。
- 默认
ft_min_word_len = 4,意味着 “a”、“to”、“of” 这类短词根本不会进索引,也就绕过了停用词检查——所以别只盯着停用词,先看长度门槛卡在哪 - 改
ft_min_word_len同样要重启 + 重建索引;MySQL 8.0+ 支持在线调整部分全文参数,但这两个仍需重启 - 如果停用词表里有 “no”、“ok”,但
ft_min_word_len = 3,那它们才会被加载并真正起效;否则直接被长度过滤掉,停用词文件再全也没用 - 建议统一设为
ft_min_word_len = 1(需重启),再靠停用词表精细控制,避免漏控



















