1. ES一定快吗?
1.1. 数据库的索引是B+tree结构
主键是聚合索引 其他索引是非聚合索引,见下图
如果是一般搜索,一般从非聚集索树上搜索出id,然后再到聚集索引树上搜索出需要的内容。
1.2. elasticsearch倒排索引原理
Term Index 以树的形式保存在内存中,运用了FST+压缩公共前缀方法极大的节省了内存,通过Term Index查询到Term Dictionary所在的block再去磁盘上找term减少了IO次数
Term Dictionary 排序后通过二分法将检索的时间复杂度从原来N降低为logN
1.3. 两者对比
对于倒排索引,要分两种情况:
1.3.1. 基于分词后的全文检索
这种情况是es的强项,而对于mysql关系型数据库而言完全是灾难
因为es分词后,每个字都可以利用FST高速找到倒排索引的位置,并迅速获取文档id列表
但是对于mysql检索中间的词只能全表扫(如果不是搜头几个字符)
1.3.2. 精确检索
这种情况我想两种相差不大,有些情况下mysql的可能会更快些
如果mysql的非聚合索引用上了覆盖索引,无需回表,则速度可能更快
es还是通过FST找到倒排索引的位置并获取文档id列表,再根据文档id获取文档并根据相关度算分进行排序,但es还有个杀手锏,即天然的分布式使得在大数据量面前可以通过分片降低每个分片的检索规模,并且可以并行检索提升效率
用filter时更是可以直接跳过检索直接走缓存
1.3.3. 多条件查询
mysql除非使用联合索引,将每个查询的字段都建立联合索引,如果是两个字段上有两个不同的索引,那么mysql将会选择一个索引使用,然后将得到的结果写入内存中使用第二个条件过滤后,得到最终的答案
es,可以进行真正的联合查询,将两个字段上查询出来的结果进行“并”操作或者“与”操作,如果是filter可以使用bitset,如果是非filter使用skip list进行
2. ES如何快速检索
笼统的来说查询数据的快慢和什么有关,首先是查询算法的优劣,其次是数据传输的快慢,以及查询数据的数据量大小。
一般的机械硬盘的读性能在100MB/s左右,再不升级高级硬件的情况下,想要优化查询性能,得从查询算法以及数据量大小两个方面做优化
首先看下es的倒排索引结构,从中分析es为了提高检索性能做了那些的努力
es会为每个term做一个倒排索引
docId |
年龄 |
性别 |
---|---|---|
1 | 18 | 女 |
2 | 20 | 女 |
3 | 18 | 男 |
年龄 |
Posting List |
---|---|
18 | 【1,3】 |
20 | 【2】 |
性别 |
Posting List |
---|---|
女 | 【1,2】 |
男 | 【3】 |