谓词下推
摘要
经常听到谓词下推
这个显得高大上的词,但一直没有真正理解到底是啥意思。查了一些资料,有了一定理解,在这里记录下。
0x01 什么是谓词
谓词,用来描述或判定客体性质、特征或者客体之间关系的词项。根据《现代汉语》的定义汉语的谓词包括动词和形容词。
谓词,英文翻译为predicate
,而谓词下推的英文定义如下:
A predicate is a function that returns bool (or something that can be implicitly converted to bool)
也就是说,谓词下推
概念中的谓词指返回bool
值即true
和false
的函数,或是隐式转换为bool的函数:
- 如SQL中的谓词主要有
LKIE
、BETWEEN
、IS NULL
、IS NOT NULL
、IN
、EXISTS
。 - 如Spark中的
input.filter(x=> x >= 5)
0x02 什么是谓词下推
谓词下推的基本思想即:
将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。
在传统数据库以及NoSql中都有谓词下推的概念。
在文件格式使用Parquet
或orcfile
时,甚至可能整块跳过不相关的文件。
可参考一篇搞懂谓词下推
0x03 谓词下推应用
3.1 Impala on Parquet
RF算法中,用了谓词下推思想。大小表进行broadcast hash join
时,用小表的join列数据构建BloomFilter,广播到大表的所有partition,使用该BloomFilter对大表join列数据进行过滤。最后将大表过滤后得到的数据与小表数据进行hashJoin。
这个过程如下图:
这样的好处是:
- 在存储层即过滤了大量大表无效数据,减少扫描无效数据列的同行其他列数据IO
- 减少存储进程到计算进程传输的数据
- 减少
hashjoin
开销
如这个sql:
select item.name, order.* from order , item where order.item_id = item.id and item.category = ‘book’
使用谓词下推,会将表达式 item.category = ‘book’
下推到join条件order.item_id = item.id
之前。再往高大上的方面说,就是将过滤表达式下推到存储层直接过滤数据,减少传输到计算层的数据量。
3.2 Hive
Hive中的Predicate Pushdown
简称谓词下推,主要思想是把过滤条件下推到map端,提前执行过滤,以减少map到reduce的传输数据,提升整体性能。
具体配置项是hive.optimize.ppd
,默认为true
,即开启谓词下推,关于join和where采用ppd
的规则如下:
结论:
- 所谓下推,即谓词过滤在
map
端执行;所谓不下推,即谓词过滤在reduce
端执行 - inner join时,谓词任意放都会下推
- left join时,左表的谓词应该写在
where
后,右表的谓词应写在后 - right join时,左表的谓词应该写在
join
后,右表的谓词应写在where
后
3.3 HBase
在HBase 0.92版以后引入了协处理器,就有复杂过滤器实现了谓词下推功能。