云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

使用MySQL全文索引,我让女同事的代码快了1000倍

jxf315 2025-04-26 19:01:43 教程文章 19 ℃

普通的工作日,很平常的一天。上午上班,和往常一样写代码,旁边的妹子有点异样,一副一筹莫展的样子,似乎被什么问题困扰了。

本着同事之间应该互相帮助的工作态度,尤其是漂亮女同事,我移动座椅到她旁边,问道:“怎么了,一副烦恼的样子,需要帮助吗?”

“我正想找你呢,你帮我看看这个问题,应该怎么优化?...” 妹子回答道,一副丧气的模样。

原来妹子碰到了这样一个难缠的问题,她负责的一个功能模块有一个关键之搜索功能,根据用户输入的关键字筛选MySQL表中的记录,这是一个模糊匹配的功能,被匹配的字段是text类型,她使用sql中的like功能实现这个需求,类似这样

select * from tb where content like '%关键字%'


在开发阶段,这么做没什么问题,所以没有人注意。然而随着项目的上线运营,数据量快速增长,这个功能运行变得很缓慢,有时候甚至要几十秒钟才能出结果,用户体验极差。运营同事将这个问题反馈到妹子这里,她不知道如何解决,所以满脸愁容。因为是一个text类型字段且使用like模糊匹配,根本没法利用索引,只能全表扫描,慢是肯定的,而且随着数据量的增长,还会变得更慢,直到最终功能不可用为止。

这种问题要是早些年还真不好解决,需要自己搭建分词系统或者用第三方搜索引擎如Sphinx、Lucene等解决,非常费事。但是到了MySQL 5.6之后,InnoDB开始支持英文全文索引,MySQL 5.7.6之后开始支持中文全文索引,利用全文索引,可以非常方便的解决like模糊匹配性能不佳问题,而我们用的MySQL,版本在这之后。

我们知道,MySQL InnoDB中当字段长度大于767bytes,相当于255个字符时,就不能建立索引,因此text类型字段不可以建立索引。全文索引可以使用大容量字段可以建立索引,只是不是索引整个字段,而是将字段的内容拆分成一个一个词语,然后索引这些词语,在查询的时候,再通过特定的算法让索引与被查询的关键字匹配,跟B+树索引的运行方式类似,快速定位到记录。


找到方法后,我和妹子找到运维,让他把生产环境那张表的数据导一份到测试环境,然后在那个需要匹配的字段上创建一个全文索引

CREATE FULLTEXT INDEX content_full_text_index ON tableName (content) WITH PARSER ngram;

其中 WITH PARSER ngram 子句的作用是使这个全文索引支持中文,然后使用如下sql语句测试了效果

select * from log where match(content) AGAINST('+关键字' in boolean  mode);


结果瞬出,几百万数据的表出结果只要几十毫秒,而妹子原来使用like时,出结果需要几十秒,足足快了一千倍。妹子看到这个结果,人都惊呆了,张大了嘴久久说不出话来。

我打断妹子发呆,说道:“你把查询语句改成全文索引匹配的语法,然后下个版本发布的时候让DBA在线上环境上建立这个索引就可以了”

妹子连连点头,激动的说不出话来。我微微一笑,转身回到自己的座位,深藏功与名。

最近发表
标签列表