MySQL 模糊搜索优化之分词优化

优化背景

当我们使用 like 进行模糊匹配是会触发全表遍历,当数据量较大时会造成数据库卡顿,导致项目运行极慢甚至服务器宕机!

我们来看个例子 :

一个文章表 :

CREATE TABLE `articles`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '文章ID',
  `title` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '文章标题',
  `content` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL COMMENT '文章内容',
  PRIMARY KEY (`id`) USING BTREE
);

当我们使用 like 进行文章内容查询时 :

select * from articles where `content` like '%go%';

此时会触发 MySQL 全表遍历,效率极低!!

使用分词技术优化模糊搜索

说明

大部分后端语言如 java、php、go 都有对应的分词包,可以实现自然语言分词,并提供词频等数据。

我们可以在文章添加后对文章标题、描述、关键字、内容等内容数据进行自然语言分词处理,将分词结果保存至分词表 :

CREATE TABLE `article_words`  (
  `id` int,
  `article_id` int,
  `word` vachar(30),

  PRIMARY KEY (`id`) USING BTREE,
  INDEX `mid`(`mid`) USING BTREE,
  INDEX `word`(`word`, `score`) USING BTREE

);

有了分词表我们再进行文章搜索时就可以通过分词表来查询到对应的文章列表 :

select a.word, b.id, b.title 
from article_words as a inner join articles as b 
on a.article_id = b.id 
where a.word = '查找关键字'

通过上面的优化,a.word 字段是索引字段,再执行文章搜索时会大幅度提高搜索效率!

分词优化方案优点

大幅度提高搜索效率

分词优化方案缺点

分词表数据量较大;

文章内容变化后需要重写分词并重新记录分词数据,维护过程有些复杂;

总结

如果您的内容库数量较大,搜索频繁,那么分词+搜索结果缓存 是一套成熟、高效的解决方案,推荐使用。