全文索引需显式创建,仅支持MyISAM和InnoDB(≥5.6),中文需ngram插件;MATCH AGAINST有自然语言、布尔、查询扩展三种模式,停用词和字符集易致搜索失败,性能受限且中文支持弱。

全文索引必须显式创建,不是加了 MATCH 就自动生效
MySQL 不会为任意字段自动建立全文索引。即使你写了 MATCH(col) AGAINST('xxx'),如果该列没建 FULLTEXT 索引,查询会退化成全表扫描,甚至报错 Can't find FULLTEXT index matching the column list。
实操建议:
- 建表时直接定义:
CREATE TABLE docs (id INT, content TEXT, FULLTEXT(content)); - 已有表需手动添加:
ALTER TABLE docs ADD FULLTEXT(content); - 仅支持
MyISAM和InnoDB引擎;InnoDB要求 MySQL ≥ 5.6,且字段不能是NULL(除非显式声明NOT NULL) - 中文需注意:默认分词基于空格和标点,对连续汉字无效 —— 实际上 MySQL 原生全文索引对中文基本不友好,除非用 ngram 插件或升级到 8.0+ 并配置
ngram_token_size
MATCH AGAINST 的三种模式:自然语言、布尔、查询扩展
不指定模式时默认是自然语言模式(NATURAL LANGUAGE MODE),它会按相关性排序,但不支持通配符、+/- 逻辑。想用布尔操作,必须显式写 IN BOOLEAN MODE。
常见错误现象:写 AGAINST('+mysql -db' IN BOOLEAN MODE) 却忘了加模式声明,结果查出一堆无关记录。
实操建议:
- 自然语言模式适合简单关键词搜索:
MATCH(title) AGAINST('database performance') - 布尔模式支持精确控制:
MATCH(content) AGAINST('+transaction -rollback' IN BOOLEAN MODE)(必须含 transaction,不含 rollback) - 查询扩展模式(
WITH QUERY EXPANSION)会自动加入相似词,但容易引入噪声,生产环境慎用 - 布尔模式中
*是后缀通配符,只支持在末尾:AGAINST('config*' IN BOOLEAN MODE)可匹配configuration,但'*fig'无效
为什么搜“MySQL”返回空?字符集和停用词是隐形杀手
即使索引建了、语法对了,也可能搜不到内容——最常见两个原因:字段字符集不匹配,或关键词被当成停用词过滤掉。
停用词表(ft_stopword_file)默认包含 “the”、“is”、“in” 等英文常见词,长度 ≤ 3 的英文词(如 “my”、“sql”)在默认配置下也会被忽略。而 “MySQL” 因含大写和符号,可能被切分为 “mysql”,再被当停用词丢弃。
实操建议:
- 检查当前停用词:
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;(InnoDB)或查系统变量ft_stopword_file - 临时绕过停用词:用布尔模式 + 引号强制匹配短词:
AGAINST('"mysql"' IN BOOLEAN MODE) - 确保字段与连接字符集一致,尤其是 utf8mb4_bin 或 utf8mb4_0900_as_cs 下大小写敏感,
MySQL和mysql可能不等价 - 最小词长由
ft_min_word_len(MyISAM)或ngram_token_size(InnoDB ngram)控制,改完需重建索引
性能陷阱:全文索引不是万能加速器
全文索引在数据量小、查询词典型时效果明显;但一旦涉及模糊前缀、多字段混合、或高并发低选择性查询,反而比 LIKE '%xxx%' 更慢,甚至锁表。
真实场景中容易踩的坑:
-
MATCH无法利用其他普通索引,WHERE MATCH() AND status = 1可能导致全索引扫描,应考虑组合索引或冗余字段预计算 - InnoDB 全文索引使用倒排表+辅助表(
FTS_*表),插入/更新有额外开销,高频写入场景要压测 - 相关性评分(
SCORE)是浮点数,不稳定,不能用于精确排序比较;不要依赖ORDER BY MATCH(...) AGAINST(...)的绝对值 - 超过 50% 行匹配的词(如 “a”、“the”)会被 MySQL 当作“太常见”而直接忽略,返回空结果 —— 这不是 bug,是设计行为
真正需要中文全文搜索时,MATCH AGAINST 往往只是权宜之计。Elasticsearch 或 Manticore 更可靠,MySQL 原生方案在中文、混合语种、复杂排序上始终有硬伤。










