MySQL 8.0 中电商搜索应使用 FULLTEXT 索引而非“倒排索引”,因其底层虽为倒排结构但仅通过 FULLTEXT 语法启用;必须配合 ngram 插件支持中文分词,且查询需严格匹配索引字段并用 MATCH() AGAINST() 语法。

倒排索引不是 MySQL 8.0 的原生索引类型,电商搜索场景里真正该用的是 FULLTEXT 索引——它底层就是倒排索引,但名字不叫“倒排索引”,MySQL 文档和执行计划里都只说 FULLTEXT。
为什么不能直接建「倒排索引」?
MySQL 不提供 CREATE INVERTED INDEX 这类语法。所谓“倒排索引”是 FULLTEXT 索引的实现原理,用户只能通过 FULLTEXT 关键字来启用它。试图在普通 B+ 树索引上模拟倒排(比如对分词后字段建普通索引)不仅无效,还会因字符串前缀不一致导致索引失效。
- 执行
CREATE FULLTEXT INDEX ft_title ON products(title)才会触发倒排结构构建 -
ALTER TABLE products ADD FULLTEXT(title, description)是安全的批量操作方式 - 建完后必须用
MATCH() AGAINST()查询,WHERE title LIKE '%xxx%'依然走不了全文索引
FULLTEXT 索引在电商搜索中必须配 ngram 才能查中文
默认 MySQL 全文索引按空格、标点分词,对中文完全无效。不配置 ngram 插件,MATCH(title) AGAINST('手机') 永远返回空结果。
- 确认插件已加载:
SHOW PLUGINS LIKE 'ngram';若未启用,需在my.cnf加ft_parser=ngram并重启 - 建索引时显式指定解析器:
ALTER TABLE products ADD FULLTEXT INDEX ft_title_ngram (title) WITH PARSER ngram -
ngram_token_size默认为 2,意味着“智能手机”会被拆成“智能”“手机”“机智”(滑动窗口),查“手机”能命中,“智”单独查不到
EXPLAIN 看不到 type=fulltext?先检查 MATCH 字段是否覆盖索引列
常见错误是索引建在 (title, description),但查询只写 MATCH(title) AGAINST(...) —— 这会导致 type=ALL 或 type=range,根本没走全文索引。
- 必须严格保持字段一致性:
MATCH(title, description) AGAINST(...)才可能命中复合全文索引 - 如果只搜标题,就单独建
FULLTEXT(title),别贪多塞 description - EXPLAIN 输出中
key字段为空、type是ALL或index,基本可判定全文索引未被使用
搜索结果不准或漏匹配?检查停用词和最小词长
MySQL 内置停用词表会过滤“的”“和”“商品”等高频无意义词;ft_min_word_len 默认为 4,导致“iPhone”“小米”这类短词建不进索引。
- 查当前停用词:
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD - 临时绕过停用词:用布尔模式
AGAINST('+手机 +壳' IN BOOLEAN MODE),加+强制包含 - 改最小词长需重启 MySQL,并重建全文索引:
SET GLOBAL innodb_ft_min_token_size = 2,然后ALTER TABLE products DROP INDEX ft_title_ngram; ALTER TABLE products ADD FULLTEXT ...
真正卡住电商搜索性能的,往往不是索引没建,而是 MATCH 和 AGAINST 的字段没对齐、中文没开 ngram、或者误把全文索引当普通索引去 LIKE 查——这些地方一错,全文索引就等于没建。



















