ElasticSearch(七):ES查询速度为什么那么快

ES使用的数据结构是倒排索引,在对搜索内容进行分词的时候,会根据搜索内容分词结果在对于的索引项里查询那些索引项包含这些分割的搜索词,之后可以直接获取索引项(Term Index)对应的索引ID来获取索引的内容。

比较ES和Mysql

Mysql索引默认使用的数据结构是B+树,B+树相对散列表(Hash)来说,在范围查询的时候,散列表并不支持。散列表的优点在与查询单个数据的时候直接get查询的,通过计算hash(key)得到索引下表,对于插入一条数据的话,执行效率为O(1)
而B+树的查询效率和树的高度有关,可以通过把二叉树变为三叉树,这样树的高度就会下降很多,这样查询数据时的 IO 次数自然也会降低,同时查询效率也会提高许多。
我们在使用Mysql模糊查询的时候,比如查询name是以张三开头的人员信息,我们的查询sql是这样的

select * from table where name like '张三%'

这样就只能查询出张三1 ,张三2这样的数据,并不能查询出张小三这样的数据,而对于ES就可以将查询数据进行分词,分词结果为张,张三,这样就可以查询出张小三这条数据。

我们知道ES会对存储的doc文档进行分词,分词的集合组成一个Term Dictory叫做单词词典。当我们的文本量巨大时,分词后的 Term 也会很多,这样一个倒排索引的数据结构如果存放于内存那肯定是不够存的,但如果像 MySQL 那样存放于磁盘,效率也没那么高。
为了提高效率,我们可以为 Term Dictionary 创建一个索引然后放入内存中。
这样便可以高效的查询 Term Dictionary ,最后再通过 Term Dictionary 查询到 Posting List。相对于 MySQL 中的 B+树来说也会减少了几次磁盘 IO。

而且再对多个字段进行查询的时候,ES利用 Bitmap了 进行优化。比如现在需要查询 name=li and age=18 的数据,这时我们需要通过这两个字段将各自的结果 Posting List 取出。
比如如下查询结果:

namePosting List
name=li[1,2,4]
age=18[1,3,4,5]

这时我们便可使用 Bitmap 的方式进行存储(还节省存储空间),同时利用先天的位与计算便可得出结果。

最后得出一个比较结果:

NameMysqlES
索引类型B+树倒排索引
效率降低树的高度,减少IO次数(磁盘查询)将Term Index存入内存,减少IO次数,查询效率更高
使用场景适用于存储结构化数据,支持join恋表查询适用于存储非结构化数据,适合全文检索

版权声明:本文为huanglu0314原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。