FULLTEXT比LIKE快因用倒排索引而非B+树,支持精准词定位;需INNODB/MYISAM引擎及CHAR/VARCHAR/TEXT类型;中文需调小innodb_ft_min_token_size或应用层预分词;*通配符仅布尔模式词尾有效。

为什么FULLTEXT比LIKE快得多
因为FULLTEXT用的是倒排索引,不是B+树。它把文本切分成词(token),每个词指向包含它的所有行ID,查 match(name) against('张三') 时直接定位词位置,不扫描整列。而 LIKE '%张三%' 在B+树里没法跳转,只能逐行比对——哪怕加了索引也无效。
FULLTEXT索引创建和基本查询写法
必须用 INNODB 或 MYISAM 引擎,且字段类型是 CHAR、VARCHAR 或 TEXT。建索引前先确认引擎:
SHOW CREATE TABLE users;
若非 INNODB,先改:
ALTER TABLE users ENGINE = INNODB;
再建全文索引:
ALTER TABLE users ADD FULLTEXT (username);
查询时不能用 WHERE username LIKE,必须用 MATCH ... AGAINST:
-
MATCH(username) AGAINST('张三' IN NATURAL LANGUAGE MODE)—— 自然语言模式,适合单关键词或短语 -
MATCH(username) AGAINST('+张 +三' IN BOOLEAN MODE)—— 布尔模式,支持+(必含)、-(排除)、*(通配)
注意:AGAINST 的参数是字符串字面量,不能是变量或拼接结果;也不能在子查询或 JOIN 条件里直接套用 MATCH。
中文搜索必须处理的两个坑
MySQL原生FULLTEXT对中文支持极差,原因有两个:
-
innodb_ft_min_token_size默认是 3,而中文单字就是1个字符,导致“张”“三”全被当停用词过滤掉 - 没有中文分词,把“张三丰”当一个完整词,搜“张三”就匹配不到
解决办法只有两个:
— 改配置(需重启MySQL,且影响全局):SET GLOBAL innodb_ft_min_token_size = 1;,再重建索引:ALTER TABLE users DROP INDEX ft_username, ADD FULLTEXT ft_username (username);
— 更可靠的做法:应用层预分词(如用jieba),把“张三丰”存成“张三丰 张三 三丰 张 三 丰”,再对这个新字段建全文索引。
布尔模式下通配符 * 的使用限制
* 只能在布尔模式生效,且必须放在词尾,比如 '张*' 可以匹配“张三”“张飞”“张无忌”,但 '*三' 或 '张*三' 都非法,会报错 ERROR 1064。
另外,* 不代表任意字符,只代表“该词的前缀扩展”,所以 '张*' 不会匹配“小张”——它不认后缀。
真正想做前后模糊,又不想全表扫描,目前最稳的路还是:前缀用 LIKE '张%' + 全文索引兜底复杂场景,别指望一个方案吃遍所有 %keyword%。


















