MySQL 中仅 InnoDB 和 MyISAM 支持 FULLTEXT 索引,但 MyISAM 已废弃且不推荐使用;InnoDB 是当前唯一推荐引擎,支持事务与行级锁,且自 5.6 起完整支持全文索引。

哪些存储引擎支持 FULLTEXT 索引?
MySQL 中只有 InnoDB 和 MyISAM 支持 FULLTEXT 索引,其他引擎(如 Memory、Archive、CSV)完全不识别 ALTER TABLE …… ADD FULLTEXT 语句,会直接报错 ERROR 1214 (HY000): The used table type doesn't support FULLTEXT indexes。
注意:MyISAM 虽然支持,但已废弃多年,官方自 MySQL 8.0.28 起默认禁用,且不支持事务、崩溃恢复弱,生产环境应排除。
-
InnoDB是当前唯一推荐的全文索引引擎,支持事务、行级锁、外键,且从 5.6 开始完整支持 - 创建时需显式指定:例如
ALTER TABLE articles ADD FULLTEXT(title, content) - 不支持在虚拟列(
GENERATED)上建FULLTEXT索引(即使该列是STORED)
MATCH() AGAINST() 的三种模式怎么选?
全文搜索必须用 MATCH(col1, col2) AGAINST(……) 语法,不能用 LIKE 或正则替代;其行为取决于 AGAINST 的第二个参数:
-
AGAINST('word' IN NATURAL LANGUAGE MODE):默认模式,适合普通查询,自动加权、忽略停用词、对短词(ft_min_word_len 和ft_stopword_file控制) -
AGAINST('word' IN BOOLEAN MODE):支持+、-、*、"phrase"等操作符,可精确控制包含 / 排除、通配、短词匹配(不受ft_min_word_len限制),但不返回相关性评分 -
AGAINST('word' WITH QUERY EXPANSION):先查一轮,再用高频词扩展二次查询,易误召回,实际极少使用
常见误用:AGAINST('mysql tutorial' IN NATURAL LANGUAGE MODE) 可能完全不命中,因为 tutorial 若在停用词表里或长度不足,会被过滤;换 BOOLEAN MODE 并写成 AGAINST('+mysql +tutorial' IN BOOLEAN MODE) 更可靠。
为什么 SELECT * 配合全文搜索会变慢?
MATCH() AGAINST() 本身很快,但若搭配 SELECT * 且结果集大,瓶颈常在回表读取完整行数据,尤其当 TEXT 或 BLOB 列存在时,InnoDB 需额外访问聚簇索引获取未包含在二级全文索引中的字段。
- 全文索引只存分词后的倒排项,不存原始文本;
SELECT title, MATCH(……) AGAINST(……)比SELECT *快得多 - 避免在
WHERE中混用全文条件和其他非索引条件(如AND status = 'draft'),否则优化器可能放弃全文索引而走全表扫描 - 若需多条件过滤,优先让全文条件做主过滤,其他条件尽量也走索引(如给
status加普通索引)
中文全文搜索为什么基本无效?
MySQL 原生全文索引按空白符和标点切词,对中文无分词能力 ——“数据库优化技巧”会被当成一个超长词,而默认 ft_max_word_len=84,但中文词通常 2–4 字,且无空格分隔,导致几乎无法命中。
- 不是配置调得不够低就能解决;根本原因是缺少中文分词器,
ft_min_word_len=2后仍只会把整字段当一个 token 处理 - 可行方案只有两个:用外部工具预处理 (如用
jieba在应用层分词后写入带空格的字段),或 换搜索引擎(Elasticsearch / Meilisearch) - MySQL 8.0+ 的
ngram插件仅支持 n-gram 切字(非词),对“数据库”切出“数”“据”“库”“数据”“据库”,召回噪音大,不推荐用于业务搜索
真正要支持中文搜索,别在 MySQL 全文索引上硬扛 —— 它的设计目标就是英文等空格分隔语言。