mysql全文索引不走b+树路径,而是基于倒排索引的独立文本检索流程:先分词,再查词典映射文档id,最后回表过滤,完全绕过b+树遍历与有序性依赖。

MySQL执行全文索引查询时,根本不是走B+树的索引查找路径,而是启动一套独立的文本检索流程——它不比较键值大小、不遍历B+树节点、也不依赖有序性。
全文索引不走B+树查找逻辑
普通B+树索引(如INDEX或PRIMARY KEY)在WHERE col = ?或WHERE col BETWEEN ? AND ?时,会从根节点逐层下降定位叶子页,利用有序性做范围跳转;而全文索引(FULLTEXT)触发的是倒排索引(Inverted Index)查表操作:MySQL先对查询词分词,再查词典映射到包含该词的文档ID列表,最后回表过滤。这个过程完全绕过B+树遍历。
这意味着:
-
MATCH(col) AGAINST('xxx')不会响应EXPLAIN中的type: range或ref,通常显示为type: fulltext - 即使你在同一列上同时建了
INDEX和FULLTEXT,MATCH()也绝不会用前者加速 - B+树索引无法优化
LIKE '%word%',但全文索引天生为此设计——不过仅限于分词后匹配,不是通配符扫描
分词行为导致结果不可预测
全文索引的执行效果高度依赖分词器输出,而MySQL内置分词器对中文基本无效(默认按空格/标点切分),英文则会自动去除停用词(如“the”、“is”)、统一小写、做词干提取(取决于ft_min_word_len和ft_stopword_file配置)。
常见现象包括:
- 查
AGAINST('running')可能命中'run'(因词干化),也可能不命中(若ft_min_word_len=4,'run'被忽略) - 中文字段建了
FULLTEXT但查不出结果——因为没装mysqlcft之类插件,或没启用ngram解析器(MySQL 5.7+支持WITH PARSER ngram) -
IN BOOLEAN MODE下+/-符号生效,但NATURAL LANGUAGE MODE下这些符号被忽略,执行逻辑完全不同
执行计划里看不到“索引合并”,但实际可能多表回查
当MATCH() AGAINST()涉及多个列(如MATCH(title, content)),且这些列属于不同B+树索引结构时,MySQL仍会把它们当作一个逻辑全文索引处理——但底层可能分别查倒排表,再取交集或并集。这不会反映在EXPLAIN的key字段中,你只看到key: NULL或key: fulltext,但实际I/O压力可能远高于单列查询。
更隐蔽的问题是:
- 全文查询返回结果默认按相关度排序(
RELEVANCE),这个分数计算本身有开销,禁用排序(加ORDER BY NULL)能提速,但多数ORM不暴露该控制点 - InnoDB的全文索引会维护辅助表(如
FTS_0000000000000123_0000000000000456_INDEX_1),这些表的更新延迟可能导致刚插入的数据查不到——不是bug,是设计使然 - MyISAM的全文索引支持
BOOLEAN MODE更早、更稳定,但InnoDB自5.6起才支持,且对事务可见性处理更复杂(需等事务提交后索引才可见)
真正容易被忽略的,是全文索引的“冷启动”成本:首次MATCH查询会触发分词缓存初始化和倒排表预热,后续查询才进入稳定态;而B+树索引只要数据页在buffer pool里,每次都是确定的树路径访问。这两者压根不在同一个性能模型里。











