MySQL中的全文本搜索是一种面向长文本内容的检索方式,它通过全文索引和匹配函数配合,完成比简单模糊查询更接近搜索引擎的检索体验。核心写法是使用 MATCH 指定参与检索的字段,再使用 AGAINST 指定关键词与检索模式。相比逐行扫描字符串,全文本搜索更关注词语拆分、匹配程度和结果排序,适合文章标题、正文、评论摘要等需要按关键词查找的场景。

一、从模糊查询到全文本搜索:为什么需要全文索引
很多开发者最初会使用 LIKE 完成关键词查询,例如在标题或正文中查找包含某个词的记录。这种方式在数据量较小、字段较短时足够直观,但面对大段文本时会出现明显问题。一方面,通配符组合容易导致索引利用受限,查询需要扫描更多行;另一方面,模糊查询只能判断字符串是否出现,很难衡量内容与关键词之间的相关程度,也难以处理多个关键词同时参与的复杂匹配。
全文本搜索的思路是先为文本字段建立专门的全文索引,把文本内容按照一定规则拆分成可检索的词项,再在查询时根据词项匹配情况返回结果。这样一来,数据库不再只是简单比较字符串,而是基于索引结构完成查找,并能给出匹配度评分。也正因为如此,MATCH 和 AGAINST 的组合不仅可以用于 WHERE 条件过滤,还可以出现在 SELECT 列表中,用来计算每条记录的相关性得分。
不过,全文本搜索并非所有场景都适合。它更适合读取多、文本长、关键词检索需求明确的业务,例如文章库、产品说明、日志摘要等。如果表中数据频繁变化,或者文本字段非常短,全文索引的维护成本可能高于收益。因此,在使用之前需要先理解它的索引建立方式、字段限制以及匹配模式。
二、建立全文索引与MATCH AGAINST的基本用法
要使用全文本搜索,必须先为参与检索的字段创建全文索引。MySQL中的全文索引适用于 CHAR、VARCHAR、TEXT 类型的字段,可以建立在单个字段上,也可以建立在多个字段组成的联合全文索引上。如果业务同时按标题和正文搜索,通常建议把两个字段放入同一个联合全文索引,以便在查询时使用统一的匹配表达式。
创建全文索引有两种常见方式。第一种是在创建表时直接声明,第二种是在已有表上追加索引。无论采用哪种方式,索引创建完成后,查询时使用的字段列表都需要与索引覆盖的字段保持一致。例如,索引建立在 title 和 content 上,那么 MATCH(title, content) 才能正确利用该索引。
从语法结构看,MATCH 负责指定要搜索的字段集合,AGAINST 负责指定搜索关键词以及可选的搜索模式。如果不写模式,默认使用自然语言搜索模式。下面的示例先创建一张文章表,并在建表时定义联合全文索引。
-- 创建文章表,并在建表时定义联合全文索引
CREATE TABLE article (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FULLTEXT INDEX ft_idx_title_content (title, content)
);
如果表已经存在,也可以单独为字段补充全文索引。为了与前面的索引名称区分,这里使用一个新的索引名作为示例。
-- 为已有表补充联合全文索引 ALTER TABLE article ADD FULLTEXT INDEX ft_idx_title_content_manual (title, content);
为了后续演示不同搜索模式,可以先插入一组测试数据。这些数据覆盖标题和正文两个字段,便于观察联合全文索引的匹配效果。
INSERT INTO article (title, content) VALUES
('MySQL基础教程', '本文介绍MySQL的基本安装和使用方法,适合新手学习'),
('MySQL全文本搜索详解', '详细讲解MySQL中MATCH和AGAINST函数的用法,以及全文索引的创建方式'),
('Python数据分析入门', '使用Python进行数据清洗和分析的基础方法介绍'),
('MySQL性能优化技巧', '分享MySQL查询优化、索引优化的实用技巧,提升数据库运行效率');
最基础的查询方式是在 WHERE 中使用相同的 MATCH 和 AGAINST 表达式,同时也可以在 SELECT 中把评分取出来,方便观察不同记录的相关性差异。
SELECT
id,
title,
content,
MATCH(title, content) AGAINST('MySQL 全文索引') AS score
FROM article
WHERE MATCH(title, content) AGAINST('MySQL 全文索引');
三、自然语言、布尔和查询扩展三种模式的差异
自然语言搜索模式是默认模式。它会对关键词进行分词处理,并尝试计算每条结果与关键词集合的整体匹配程度。评分越高,通常表示该记录与搜索词越相关。这种模式适合普通用户输入一句话或几个词进行检索,不需要编写复杂规则。
布尔搜索模式则更强调控制力。通过运算符,可以要求某个词必须出现、必须不出现,或者调整某个词的权重,还可以使用前缀通配。它适合对检索结果有明确约束的场景,比如必须包含某个核心词、排除某个干扰词。使用布尔模式时,需要在 AGAINST 中显式指定 IN BOOLEAN MODE。
查询扩展搜索模式适合关键词较短、表达不够完整的情况。它会先根据原始关键词进行一次搜索,再把第一次结果中出现的相关词纳入第二次搜索,从而扩大召回范围。这种方式可能提高查全率,但也可能引入更多不够精确的结果,因此更适合对召回要求高、对精度要求相对宽松的场景。
-- 自然语言搜索模式,同时返回匹配度评分
SELECT
id,
title,
content,
MATCH(title, content) AGAINST('MySQL 全文索引') AS score
FROM article
WHERE MATCH(title, content) AGAINST('MySQL 全文索引');
在布尔模式中,常用运算符分别承担不同职责。加号表示必须包含,减号表示必须排除,大于号用于提高权重,小于号用于降低权重,星号用于前缀通配。
- +:表示关键词必须出现在结果中
- -:表示关键词不能出现在结果中
- >:表示提高该关键词的匹配权重
- <:表示降低该关键词的匹配权重
- *:表示通配符,匹配以该关键词开头的词
-- 必须包含MySQL,不能包含Python,并且匹配全文索引相关内容
SELECT id, title, content
FROM article
WHERE MATCH(title, content) AGAINST('+MySQL -Python 全文索引' IN BOOLEAN MODE);
-- 必须包含MySQL,同时提高全文本搜索关键词的匹配权重
SELECT id, title, content
FROM article
WHERE MATCH(title, content) AGAINST('+MySQL >全文本搜索' IN BOOLEAN MODE);
查询扩展模式的写法相对简单,只需要在 AGAINST 中加入 WITH QUERY EXPANSION。这种模式不需要手动指定复杂的布尔规则,而是由数据库根据第一次查询结果自动扩展检索范围。
-- 查询扩展搜索模式
SELECT id, title, content
FROM article
WHERE MATCH(title, content) AGAINST('全文本搜索' WITH QUERY EXPANSION);
四、中文检索支持与使用限制
如果数据中包含大量中文,默认的全文解析器往往无法满足中文分词需求,因为中文词语之间没有天然空格,检索效果会受到明显影响。此时可以使用 ngram 全文解析器。创建全文索引时指定该解析器后,MySQL会按照固定长度切分文本,从而让中文内容也能参与全文检索。
除了中文分词,全文本搜索还有一些天然限制需要特别注意。首先是关键词长度限制。默认情况下,过短的词不会进入索引,也无法被检索到。如果业务中确实存在大量短词检索需求,需要调整相关参数,并在调整后重建全文索引。其次是高频词限制。在自然语言模式下,如果一个关键词出现在过多记录中,会被视为噪音词,可能不会返回预期结果。
写入性能也是选型时必须考虑的因素。全文索引不是建立后就不再变化,新增、修改、删除文本数据都会带来索引维护开销。对于写入非常频繁、文本字段不断更新的表,需要评估查询收益与写入成本之间的关系。如果业务允许,可以把全文检索与主业务写入分离,或者只在相对稳定的内容表上使用全文索引。
-- 创建支持中文分词的全文索引
ALTER TABLE article
ADD FULLTEXT INDEX ft_idx_title_content_cn (title, content) WITH PARSER ngram;
-- 基于中文关键词进行布尔模式搜索
SELECT id, title, content
FROM article
WHERE MATCH(title, content) AGAINST('数据库优化' IN BOOLEAN MODE);
综合来看,MySQL的全文本搜索通过全文索引、MATCH 函数和 AGAINST 函数的组合,为长文本字段提供了更高效的检索方式。自然语言模式适合常规搜索,布尔模式适合精确控制,查询扩展模式适合提高召回范围。在实际使用中,还需要结合中文分词、最小词长、索引维护成本等因素一起设计,才能让全文搜索在查询效率和业务效果之间取得平衡。
MySQL全文本搜索MATCH_AGAINST全文索引修改时间:2026-07-10 20:09:32