mysql使用match()/against()实现全文搜索,sql server才用contains;match()列必须与fulltext索引定义完全一致,否则报错;支持自然语言、布尔和查询扩展三种模式,布尔模式支持+/-等逻辑操作符。

MATCH AGAINST 和 CONTAINS 不是同一种机制,也不能混用;MySQL 用 MATCH()/AGAINST(),SQL Server 才用 CONTAINS。选错函数或引擎,查询直接不生效。
MySQL 中 MATCH() 必须严格匹配全文索引定义
你写 MATCH(title, body),但索引只建在 title 上,MySQL 就会报错:ERROR 1191: Can't find FULLTEXT index matching the column list。这不是语法错误,是元数据校验失败。
- 索引列顺序必须完全一致:如果建的是
FULLTEXT(body, title),那MATCH()里也得写成MATCH(body, title),不能调换 - 不能多列、不能少列、不能用别名或表达式 ——
MATCH(CONCAT(title, ' ', body))是非法的 - InnoDB 表需确认
innodb_ft_min_token_size设置(默认 3),否则像 "it" 这类短词会被忽略,查不到
SQL Server 的 CONTAINS 对引号和通配符极其敏感
CONTAINS(address, 'beijing') 能查到 “Beijing Road”,但 CONTAINS(address, 'beijing*') 反而可能查不到 —— 因为 * 在 CONTAINS 中不是通配符,而是词干扩展符,且必须紧跟在双引号内:'"beijing*"' 才合法。
- 词组必须用双引号包裹:
'"hebei province"',单引号里再套双引号 - 逻辑操作符(
AND、OR、AND NOT)必须大写,小写会被当作文本字面量 -
NEAR不是距离控制,而是邻近算子,它依赖于全文索引的断词结果,两次重建索引后行为可能变化
AGAINST() 的模式切换决定结果是否“精准”
默认自然语言模式(IN NATURAL LANGUAGE MODE)返回按相关性排序的结果,但不保证包含所有关键词;要强制命中某个词,必须切到布尔模式:AGAINST('+mysql +tutorial' IN BOOLEAN MODE)。
-
+表示必须出现,-表示必须排除,>/调整词权重,但这些只在布尔模式下生效 - 自然语言模式下,
AGAINST('security')可能返回含 “secure” 的记录(词形还原),这不是 bug,是设计行为 - 布尔模式不计算相关性得分,
SELECT ..., MATCH(...) AGAINST(...)返回的 score 恒为 0 或 1
全文索引本身就有不可绕过的限制
无论用哪个函数,底层都依赖全文索引,而这个索引天生不适合“精准”二字:停用词被过滤(如 “the”、“and”)、短词被截断、中文需额外配置分词器(MySQL 原生不支持中文分词)。
- MyISAM 默认停用词表有 543 个英文词,InnoDB 可自定义但需重启服务重载
- 想搜 “C++”?默认会被拆成 “c” 和 “” —— 因为
+是布尔操作符,不是字符,得用转义或改用LIKE配合前缀索引 - 没有全文索引的列,
MATCH()直接报错;没启用全文索引功能的 SQL Server 实例,CONTAINS会提示Full-Text Search is not enabled
真正需要“精准”的场景,比如订单号、SKU、身份证号搜索,别碰全文索引 —— 它的设计目标是“找大致相关的文本”,不是“精确匹配字符串”。该用 = 就用 =,该建普通 B+Tree 索引就建,全文索引只是另一个工具,不是万能解药。











