用了Elasticsearch后,查询起飞了( 四 )
讲完了压缩 , 我们再来讲讲联合查询 。 先讲简单的 , 如果查询有filtercache , 那就是直接拿filtercache来做计算 , 也就是说位图来做AND或者OR的计算 。
如果查询的filter没有缓存 , 那么就用skiplist的方式去遍历磁盘上的postingslist 。 
以上是三个postinglist 。 我们现在需要把它们用AND的关系合并 , 得出postinglist的交集 。
首先选择最短的postinglist , 逐个在另外两个postinglist中查找看是否存在 , 最后得到交集的结果 。
遍历的过程可以跳过一些元素 , 比如我们遍历到绿色的13的时候 , 就可以跳过蓝色的3了 , 因为3比13要小 。
用skiplist还会带来一个好处 , 还记得前面说的吗 , postingslist在磁盘里面是采用FOR的编码方式存储的 。
会把所有的文档分成很多个block , 每个block正好包含256个文档 , 然后单独对每个文档进行增量编码 , 计算出存储这个block里面所有文档最多需要多少位来保存每个id , 并且把这个位数作为头信息(header)放在每个block的前面 。
因为这个FOR的编码是有解压缩成本的 。 利用skiplist , 除了跳过了遍历的成本 , 也跳过了解压缩这些压缩过的block的过程 , 从而节省了cpu 。
总结
下面我们来做一个技术总结:
①为了能够快速定位到目标文档 , ES使用倒排索引技术来优化搜索速度 , 虽然空间消耗比较大 , 但是搜索性能提高十分显著 。
②为了能够在数量巨大的terms中快速定位到某一个term , 同时节约对内存的使用和减少磁盘io的读取 。
lucene使用''termindex→termdictionary→postingslist''的倒排索引结构 , 通过FST压缩放入内存 , 进一步提高搜索效率 。
③为了减少postingslist的磁盘消耗 , lucene使用了FOR(FrameofReference)技术压缩 , 带来的压缩效果十分明显 。
④ES的filter语句采用了RoaringBitmap技术来缓存搜索结果 , 保证高频filter查询速度的同时降低存储空间消耗 。
⑤在联合查询时 , 在有filtercache的情况下 , 会直接利用位图的原生特性快速求交并集得到联合查询结果 , 否则使用skiplist对多个postingslist求交并集 , 跳过遍历成本并且节省部分数据的解压缩cpu成本 。
Elasticsearch的索引思路
将磁盘里的东西尽量搬进内存 , 减少磁盘随机读取次数(同时也利用磁盘顺序读特性) , 结合各种压缩算法 , 用及其苛刻的态度使用内存 。
所以 , 对于使用Elasticsearch进行索引时需要注意:
不需要索引的字段 , 一定要明确定义出来 , 因为默认是自动建索引的 。 同样的道理 , 对于String类型的字段 , 不需要analysis的也需要明确定义出来 , 因为默认也是会analysis的 。 选择有规律的ID很重要 , 随机性太大的ID(比如Java的UUID)不利于查询 。最后说一下 , 技术选型永远伴随着业务场景的考量 , 每种数据库都有自己要解决的问题(或者说擅长的领域) , 对应的就有自己的数据结构 , 而不同的使用场景和数据结构 , 需要用不同的索引 , 才能起到最大化加快查询的目的 。
这篇文章讲的虽是Lucene如何实现倒排索引 , 如何精打细算每一块内存、磁盘空间、如何用诡谲的位运算加快处理速度 。
但往高处思考 , 再类比一下MySQL , 你就会发现 , 虽然都是索引 , 但是实现起来 , 截然不同 。 笼统的来说 , B-tree索引是为写入优化的索引结构 。
当我们不需要支持快速的更新的时候 , 可以用预先排序等方式换取更小的存储空间 , 更快的检索速度等好处 , 其代价就是更新慢 , 就像ES 。
作者:Richard_Yi
- 成年后,近视度数还会再加深吗 蚂蚁庄园今日答案6月29日
- 为验证人类和黑猩猩,是否会产生新的后代,科学家找来5位姑娘!
- 芯片|外媒:老美“加码”相关限制后,更为“棘手”的后果已经出现!
- 显卡|3个不买RTX 3080的理由:没钱只能排最后
- 油价|年内第十涨后 油价或将迎下调:会持续降价吗?专家回应
- 科学家为何要在太空放火?会有什么后果?答案让人意外
- 图像处理|懂点AI或图像处理,一般性抠图作图连PS都不用了
- 芯片|二手商品可以放心买吗?体验转转买手机后,我有话说
- 灵魂就是暗物质?科学家发现,人死后磁场会放大40多倍消散于宇宙
- 机器人|华为机器人新专利上线 网友:先有华为后有天开上鸿蒙如升仙
