navicat 不执行全文搜索逻辑,仅辅助编写 match() 和 against() 语句并确保索引存在;其图形界面常无法成功创建全文索引,推荐手动执行 alter table ... add fulltext index;mysql 5.7+ innodb 支持全文索引,但需确认引擎、字段类型(varchar/text)、字符集(utf8mb4)及排序规则;against() 仅支持一种模式(自然语言、布尔或查询扩展),不可混用;中文检索须配置 ngram_token_size=1 并重建索引;相关性分数仅当前查询内有效,不可跨场景比较;应结合 explain 验证是否真正使用全文索引。
navicat 本身不直接执行全文搜索逻辑,它只是帮你写对 match() 和 against() 的 sql,并确保底层索引存在——而这个索引,经常在 navicat 图形界面里创建失败。
Navicat 创建全文索引常失败,优先用 SQL 手动建
MySQL 5.7+ 的 InnoDB 表支持全文索引,但 Navicat 的表设计器在某些版本(尤其是旧版或非 UTF8MB4 环境)下会静默忽略 FULLTEXT 类型选择,或报“不支持的索引类型”错误。
- 必须确认存储引擎是
InnoDB或MyISAM(MyISAM已弃用,不推荐) - 字段类型只能是
VARCHAR、TEXT或其变体(TINYTEXT、MEDIUMTEXT等) - 字符集建议用
utf8mb4,且排序规则为utf8mb4_0900_as_cs或兼容分词的 collation - 直接在 Navicat 查询编辑器中运行:
ALTER TABLE `articles` ADD FULLTEXT INDEX `ft_title_body` (`title`, `body`);
MATCH() 和 AGAINST() 的三种模式不能混用
同一个 WHERE 子句里,AGAINST() 只能指定一种模式:自然语言、布尔、或查询扩展。Navicat 的自动补全有时会漏掉 IN NATURAL LANGUAGE MODE,导致语法错误或行为异常。
- 自然语言模式(默认):
MATCH(title) AGAINST('数据库管理员')—— 返回带相关性分数的行,不支持操作符 - 布尔模式(需显式声明):
MATCH(title) AGAINST('+数据库 -管理员' IN BOOLEAN MODE)—— 支持+、-、*、双引号短语等 - 查询扩展模式:
MATCH(title) AGAINST('mysql' WITH QUERY EXPANSION)—— 第二次搜索会基于第一次结果自动追加关键词,慎用于高并发场景 - 错误示例:
MATCH(title) AGAINST('mysql' IN BOOLEAN MODE) OR title LIKE '%mysql%'——OR后面的LIKE会让整个条件无法使用全文索引
中文全文检索必须调低 ngram_token_size 并重建索引
MySQL 原生全文索引对中文支持极弱,默认按空格/标点切词,英文单词可分,中文却几乎不分——所以你搜“数据库”,很可能什么都匹配不到。
- 修改 MySQL 配置文件(如
my.cnf或my.ini),在[mysqld]段加入:ngram_token_size = 1<br>ft_min_word_len = 1
- 重启 MySQL 服务(仅改配置不重启无效)
-
关键一步:已有全文索引必须删除并重建,否则新配置不生效:
DROP INDEX `ft_title_body` ON `articles`;<br>ALTER TABLE `articles` ADD FULLTEXT INDEX `ft_title_body` (`title`, `body`);
- 验证是否生效:查
SELECT * FROM information_schema.INNODB_FT_CONFIG;,若value列含1,说明已启用 ngram 解析器
相关性分数不是万能的,别把它当排序唯一依据
你可以在 SELECT 列表里写 MATCH(title) AGAINST('DBA') AS score 来看分数,但这分数只在当前查询上下文中相对有效,跨表、跨词、跨数据量时不可比。
- 分数受停用词(stopword)影响大,比如“的”、“和”、“在”默认被忽略,即使你设了
ngram_token_size = 1也不一定生效 - InnoDB 的全文索引不支持自定义停用词表(MyISAM 支持,但已淘汰)
- 如果业务强依赖排序质量,建议把
MATCH()...AGAINST()当作快速粗筛,再用应用层做二次关键词加权或语义相似度计算 - Navicat 的“查询分析器”能帮你看到该语句是否真走了全文索引(看
type = fulltext和key列是否非空),而不是退化成全表扫描
真正卡住人的地方,往往不是语法写错,而是索引没生效、配置没重启、或者中文分词根本没启动——这些细节在 Navicat 界面里完全不提示,只能靠日志和 EXPLAIN 交叉验证。











