首页/数据/SQL 速查/全文索引与 MATCH AGAINST
性能与执行计划72 条

全文索引与 MATCH AGAINST

按词做文本检索:MySQL 的 FULLTEXT(InnoDB 支持)与 PostgreSQL 的 tsvector + GIN 都能避开前置通配的全扫描。

SQL 速查数据更新于 2026-10-13

全文索引是什么

全文索引按「词」而不是按「前缀」检索:MySQL 用 FULLTEXT 索引配 MATCH ... AGAINST,InnoDB 自 5.6 起支持;PostgreSQL 用 tsvector 列加 GIN 索引,用 @@ 搭配 to_tsquery / plainto_tsquery 查询。它能避开 LIKE '%词%' 那种前置通配造成的全表扫描,但命中效果完全由分词规则决定。

基本信息

MySQL 语法ALTER TABLE ... ADD FULLTEXT INDEX;查询用 MATCH(列) AGAINST('串' [模式])
PostgreSQL 语法tsvector 生成列 + GIN 索引 + @@ 匹配
分词方式MySQL 默认按空格与标点切分,中文可配 ngram 解析器;PG 用文本搜索配置
最小词长MySQL InnoDB 默认 innodb_ft_min_token_size=3,更短的词不入索引
检索模式MySQL 自然语言模式按相关度排序,布尔模式支持 + - * 等操作符

典型使用场景

  • 文章、商品标题与正文的关键词检索
  • 后台搜索框替代 LIKE '%词%' 的全表扫描
  • 布尔模式做包含与排除,例如「必须含 A 且不含 B」
  • 按相关度取结果 Top N,替代手工排序规则
  • 多语言内容按对应文本搜索配置分词

MySQL 建索引与查询

MySQL 建索引与查询
ALTER TABLE articles ADD FULLTEXT INDEX ft_title_content (title, content);   -- 建全文索引

-- 布尔模式:+ 表示必须包含,- 表示必须排除
SELECT id, title FROM articles
WHERE MATCH(title, content) AGAINST('+mysql -oracle' IN BOOLEAN MODE);

-- 自然语言模式:返回值就是相关度分数,可用来排序
SELECT id, title, MATCH(title, content) AGAINST('mysql 索引') AS score
FROM articles
WHERE MATCH(title, content) AGAINST('mysql 索引')
ORDER BY score DESC;

PostgreSQL 建索引与查询

PostgreSQL 建索引与查询
-- 生成列保存分词结果,写入时自动更新
ALTER TABLE articles ADD COLUMN tsv tsvector
  GENERATED ALWAYS AS (to_tsvector('simple', title || ' ' || content)) STORED;
CREATE INDEX idx_articles_tsv ON articles USING GIN (tsv);

-- plainto_tsquery 把普通文本转成查询,不会把符号当运算符
SELECT id, title FROM articles
WHERE tsv @@ plainto_tsquery('simple', 'mysql 索引')
ORDER BY id;

两库对照

维度MySQL FULLTEXTPostgreSQL
索引对象建在表上的 FULLTEXT 索引GIN 索引建在 tsvector 列上
查询写法MATCH(列) AGAINST('串' 模式)tsvector @@ tsquery
中文支持需配置 ngram 解析器需安装对应分词扩展
相关度AGAINST 的返回值即分数ts_rank / ts_rank_cd
短词限制低于 innodb_ft_min_token_size 不入索引无同类硬限制,按配置分词
最小词长与停用词会让某些词根本查不到:搜不到时先确认 innodb_ft_min_token_size 与停用词列表,而不是先怀疑索引没建成功。
全文索引的写入门槛高于普通索引:每次写入都要重新分词。另外 InnoDB 全文索引里,未提交事务插入的行对全文检索不可见,刚写入马上搜索可能查不到。

易错点

  • 搜索词低于最小词长:默认配置下过短的词不入索引,结果直接为空,需要调整 innodb_ft_min_token_size 并重建索引
  • 把全文索引当模糊匹配替代品:LIKE '%xx%' 匹配子串,全文索引按词匹配,语义不同,替换前先确认业务预期
  • 中文场景沿用默认解析器:默认按空格切分,中文长句会被当成一个整词,需配 ngram 或对应分词扩展
  • 刚写入就搜索却查不到:InnoDB 全文索引在提交后才更新,事务未提交的行不可见
  • 忽略停用词表:常见词被当作停用词过滤掉,搜索无结果也不报错,排查前先看停用词配置

数据来源与参考

  • MySQL 8.0 Reference Manual · Full-Text Search Functions
  • PostgreSQL Documentation · Full Text Search
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌