前言, 为什么会注意到mysql的fulltext?   nima, 还是上次innodb转成tokudb引擎的事,这次alter修改表引擎的时候,提示percona tokudb是不支持fulltext索引的.

报错信息是这样的.

FullText 全文索引? 我什么时候使用过这个索引类型了, 来看看他的表结构… 


话说mysql innodb在5.6.4以后就有了fulltext全文索引, 虽然这个表的字段有全文索引,但我这边没用体验过,因为公司用Elasticsearch来做 “内容+标题”的索引。

文章写的不是很严谨,欢迎来喷,另外该文后续有更新的,请到原文地址查看更新。

http://xiaorui.cc/2016/02/03/%E6%B5%85%E8%B0%88mysql-fulltext%E5%85%A8%E6%96%87%E7%B4%A2%E5%BC%95%E7%9A%84%E4%BC%98%E7%BC%BA%E7%82%B9/


Mysql FullText全文索引语法是这样的.

SELECT * FROM articles WHERE match(aname,bname) against(‘+xiaorui -rfyiamcool‘ IN BOOLEAN MODE);

这种语法有3个关键字: + 代表 AND 含有,- 代表 not 不含有, no 代表 OR或 .  


in boolean mode 布尔模式,我推荐大家使用这个模式,往往不加这模式,你会发现啥都搜不到。 Boolean帮你做了一些匹配方面的适配,另外Boolean虽然可以拿到数据,但有些概率在里面的。 

in natural language mode 大小写模式

MySQL的FULLTEXT怎么分词的:


字母、数字、底线的组合视为一个字,不会把底线断字。会被分词的字符有:空白、逗号(,)与点(.),英文一般一个词一个空格,中文就不同了,所以中文需要自己分词了。

#我们先来验证下是否可以匹配到bmw.


#我们再来搜索下bmw的bm字符, 结果是无法命中结果.


#同样的bm查询,如果使用in boolean mode查询的化,会发现速度快,而且可以准确的命中.

# 通过boolean模式查询手机

另外match against也存有and not or的用法.   但问题是搜索出来的结果有些怪异,但还能接受.

#把含有meizu,不含有logo的取出来. 看起来这结果也是合理的.

#我们需要注意的是,只要涉及到汉字查询就不行了,另外涉及到分词不合理的情况也是无法命中的. 

#我们继续来看看由于分词情况引起的查询误差,下面的语句是含有meizu,不含有pro的匹配,但是我们看到结果里是有pro字符串的.  

#我不想要xts,但是返回的结果确含有xts字符串. 


搜索中文的时候最好加上通配符*符号,不然是搜不到汉字.

最后总结:

Mysql这fulltext性能看起来还行,组合查询的精度有些差,mysql fulltext跟Elasticsearch的索引都有个打分机制,也就是匹配相似度. 经过我的测试发现fulltext在单个词或者字符查询命中率还是可以的。

其实我们这就算大量的使用Elasticsearch做全文索引,分词是使用Elasticsearch最火的ik加自定义的词库包,但还是经常有因为分词问题引起数据无法命中的情况。

现在不知道mysql5.7是否可以自定义中文分词词库,如果不能的话,果断推荐大家使用Sphinx或Lucene方案.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

发表评论