分享

什么是谓词下推、映射下推

pig2 发表于 2019-11-8 18:57:49 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 2189

咱们VIP成员白杨,研究了抛出了Parquet问题。

详细可参考
大数据列式存储格式必读:列式存储格式Parquet详解
https://www.aboutyun.com/forum.php?mod=viewthread&tid=27955


原文待讨论内容如下
映射下推(Project PushDown)
说到列式存储的优势,映射下推是最突出的,它意味着在获取表中原始数据时只需要扫描查询中需要的列,由于每一列的所有值都是连续存储的,所以分区取出每一列的所有值就可以实现TableScan算子,而避免扫描整个表文件内容。

在Parquet中原生就支持映射下推,执行查询的时候可以通过Configuration传递需要读取的列的信息,这些列必须是Schema的子集,映射每次会扫描一个Row Group的数据,然后一次性得将该Row Group里所有需要的列的Cloumn Chunk都读取到内存中,每次读取一个Row Group的数据能够大大降低随机读的次数,除此之外,Parquet在读取的时候会考虑列是否连续,如果某些需要的列是存储位置是连续的,那么一次读操作就可以把多个列的数据读取到内存。

谓词下推(Predicate PushDown)
在数据库之类的查询系统中最常用的优化手段就是谓词下推了,通过将一些过滤条件尽可能的在最底层执行可以减少每一层交互的数据量,从而提升性能,例如”select count(1) from A Join B on A.id = B.id where A.a > 10 and B.b < 100”SQL查询中,在处理Join操作之前需要首先对A和B执行TableScan操作,然后再进行Join,再执行过滤,最后计算聚合函数返回,但是如果把过滤条件A.a > 10和B.b < 100分别移到A表的TableScan和B表的TableScan的时候执行,可以大大降低Join操作的输入数据。

无论是行式存储还是列式存储,都可以在将过滤条件在读取一条记录之后执行以判断该记录是否需要返回给调用者,在Parquet做了更进一步的优化,优化的方法时对每一个Row Group的每一个Column Chunk在存储的时候都计算对应的统计信息,包括该Column Chunk的最大值、最小值和空值个数。通过这些统计值和该列的过滤条件可以判断该Row Group是否需要扫描。另外Parquet未来还会增加诸如Bloom Filter和Index等优化数据,更加有效的完成谓词下推。

在使用Parquet的时候可以通过如下两种策略提升查询性能:1、类似于关系数据库的主键,对需要频繁过滤的列设置为有序的,这样在导入数据的时候会根据该列的顺序存储数据,这样可以最大化的利用最大值、最小值实现谓词下推。2、减小行组大小和页大小,这样增加跳过整个行组的可能性,但是此时需要权衡由于压缩和编码效率下降带来的I/O负载。


谓词下推、映射下推这两个是非常抽象的:

通过讨论我们得出如下结论:
映射下推,有点像数据库的表映射为Java中的一个类,比如一个用户表中有多个字段,用户名,id,班级,学校等。不全部映射,而只是映射,姓名和id。这就是映射下推。映射下推的目的就是不用全部扫描,跳过无关的内容。

谓词下推概念中的谓词指返回bool值即true和false的函数,或是隐式转换为bool的函数:
如SQL中的谓词主要有 LKIE、BETWEEN、IS NULL、IS NOT NULL、IN、EXISTS。
如Spark中的input.filter(x=> x >= 5)


推的基本思想即:
将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。
例如:在MapReduce中,谓词下推在mapper中执行处理数据属于谓词下推,可以省略reduce的处理。







没找到任何评论,期待你打破沉寂

关闭

推荐上一条 /2 下一条