ElasticSearch系列-初识弹性搜索小姐姐,你该和Like模糊查询说再见了!

年底跳槽涨薪技术哪家强,还得和靓仔学Java!

临近年关,作为程序员离不开的是跳槽涨薪的话题,而最近也在公司负责搭建ElasticSearch作为Hbase二级索引的架构。在此以ElasticSearch作为一个系列与大家分享。

何为弹性搜索

是不是很好奇为啥叫弹性搜索。这是我们家可爱的测试小姐姐,第一次见ElasticSearch就给他起了个好听的中文名:弹性搜索,挺可爱的样子。 步入正题,ElasticSearch的官网自我介绍是这样的:Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎。 而通常我们会给ElasticSearch贴上下面的标签:全文检索、倒排索引、搜索引擎。

踏出MySQL的第一步

MySQL作为大家接触最多,也最熟悉的数据库,他的重要性是不容置疑的。也许你用他处理一切数据存储都挺好,也许你使用MySQL已经遇到了一些问题,无论如何,都不妨来试一试用ElasticSearch来开始替代MySQL做一些数据存储。

在使用MySQL的时候,一定写过这样的语句:

select * from tableName where name like "%XX%";

你也一定经常看到这样的建议: MySQL模糊查询不要将%写在左侧,这样会导致索引失效!这句话并没有任何错误,但是当产品小姐姐给的需求就是模糊查询呢?你敢大声告诉他这个需求不合理,索引会失效吗?我想你不会拒绝这样的需求的,那么你脑海里闪现的解决方案有哪些呢?

  1. 随缘

可能做完了功能,使用感觉没有任何毛病,什么索引失效不失效的,我完全感觉不到,查询速度也没有感觉到降低。那么我可以大胆的猜测,表中的数据量可能也就几万上下。数据量增长也非常低。这样的情况下去考虑性能也确实不太人道,先考虑产品能否生存才是王道!

  1. 禁用模糊搜索

当项目运行一段时间,数据量上去了,慢SQL日志一天跑不停,遂查找到原因是因为模糊搜索引起,经商量,砍掉~!! 当你无法用技术解决的时候,砍掉一部分功能以保证可用性也是一种选择

  1. 以MySQL的方式进行优化

在网上看到很多优化的例子,这里我们直接使用MySQL来做验证,看最终的优化效果!
首先使用Java代码造数5000万条,造数代码已收录至MySQL造数

在MySQL使用如下两条SQL语句进行查询,查询结果一点都不出人意料

select * from emp where age > 15 and user_name like "张%" limit 100;
select * from emp where age > 15 and user_name like "%朔%" limit 100;

众所周知,MySQL的Like模糊查询,当%处于模糊匹配左侧时,无法使用到索引,会进行全表检索,因此效率低,而第一条语句左侧没有%,则可以使用到索引。

提问: 这里如果只使用user_name作为条件,效率其实还是可以接受的,聪明的你,知道是为什么吗?

MySQL在5.6提供了全文检索对InnoDB的的支持,全文检索可以理解为一种索引方式,称作为倒排索引,后面详细讲ElasticSearch的时候会讲到,这里暂时略过。

下面测试通过email字段不同情况下的模糊查询。

select * from emp where email like "5291%" and age = 15 ;
#fulltext语法
select * from emp where MATCH(email) AGAINST("5921*" IN BOOLEAN MODE) and age = 15
索引 消耗时间
无索引 383秒
btree索引 588秒
fulltext索引 89秒

通过结果,可以看到fulltext对于模糊查询的优化还是有较大的提升,但89秒任然是业务不可能接受的查询时间,下面就让我们见识以下ElasticSearch的魔力吧。

ElasticSearch查询

首先安装好ElasticSearch,本案例选择的是ES7.10.1,是目前最新的发布版本,可视化界面选择cerebro。同时,需要从文件中将前面写好的数据导入到ElasticSearch,这里选择使用Datax进行数据导入,如果不清楚如何使用Datax,可移步 Datax基本使用

沒有对比就没有伤害,同样的数据量,同样的数据,同样的查询,同样的结果,而耗时确实天差地别,从图中看到,使用ElasticSearch查询email以5921开头且年龄为15岁的数据,总条数45条,耗时491ms,没有经过测试,你都不一定相信这是真实发生的,MySQL最慢有400多秒,而ElasticSearch仅花费400多毫秒,足足差了近1000倍!

技术选型

上面的查询效率对比,毫无疑问,MySQL完败,但这并不代表你就可以抛弃MySQL而全面拥抱ElasticSearch。
MySQL是属于关系型数据库,善于处理结构化数据,同时对于关联查询也有很好的支持,在5.6之后,在数据量不是很大的情况下,基本上能很好的应对除全文检索以外的场景。而ElasticSearch是NoSQL,存储非结构化数据,虽然能够进行关联、聚合等操作,但通常都不会建议使用ElasticSearch来处理这些场景,我们对ElasticSearch和MySQL做以下对比。

MySQL ElasticSearh 说明
实时性 实时 近实时 ElasticSearch的写入效率比MySQL低,如果对实时性要求非常高,那么优先选择MySQL
数据结构 完全结构化数据 非结构化数据 这没什么好说的,结构化数据优选MySQL,但如果同时有搜索的要求,可以考虑ElasticSearch
事务 支持 不支持 ElasticSearch是不支持事务的,对事务有严格要求,请使用MySQL
查询性能 数据量增大后性能降低 支持较大数据量 ElasticSearch更适用于搜索场景,如果有搜索场景,毫不犹豫选择ElasticSearch

写在最后

无论你当前数据量如何,场景如何,我都建议你可以将ElasticSearch利用起来,你会发现另外一片天地。you know, for search !

你可能感兴趣的