一文详解Hive的谓词下推

大数据那些事

共 3818字,需浏览 8分钟

 ·

2021-07-31 11:40

点击上方蓝字
关注我吧


谓词,是指用来描述或判断客体性质、特征或客体之间关系的词项。在SQL中即返回值为布尔值的函数。

谓词下推,在Hive中叫Predicate Pushdown,含义是指在不影响结果的前提下,尽量将过滤条件提前执行,使得最后参与join的表的数据量更小。谓词下推后,过滤条件将在map端提前执行,减少map端输出,降低了数据传输IO,节约资源,提升性能。在Hive中通过配置hive.optimize.ppd参数为true,开启谓词下推,默认为开启状态。


1

表的分类


首先定义一下参与join的表的类型,共分4类。

1.  Preserved Row table:保留表

        a left (outer) join b      中的 a 表;

        a right (outer) join b    中的 b 表;

        a full outer join b         a 和 b 表都是 保留表。

2.  Null Supplying table:提供null值的表,也就是 非保留表,在join中如果不能匹配上的使用null填充的表。

        a left (outer) join b     中的 b 表; 

        a right (outer) join b   中的 a 表,

        a full outer join b        a 和 b 表都是 null值保留表

3.  During Join predicate:join中谓词,就是on后面的条件。

        R1 join R2 on R1.x = 5   --> R1.x = 5就是join中谓词

4.  After Join predicate:join后谓词,就是where后面的条件。

        a left join b where a.t=1  --> a.t=1 就是join后谓词


2

Left outer Join & Right outer Join

!!!测试时,关闭 cbo 优化:set hive.cbo.enable=false

案例一:过滤条件写在 where, 且是 保留表的字段    

explain

select o.id from bigtable b

left join bigtable o 

where b.id <= 10;

 --> 可以谓词下推(能在 map 阶段提前过滤)


案例二:过滤条件写在 where, 且是 非保留表的字段   

explain

select b.id,o.id from bigtable b

left join bigtable o

where o.id <= 10;

--> 不可以谓词下推(能在 map 阶段提前过滤)


案例三:过滤条件写在 on, 且是 保留表的字段        

explain

select o.id from bigtable b

left join bigtable o

on b.id <= 10;

--> 不可以谓词下推(不能在 map 阶段提前过滤)


案例四:过滤条件写在 on, 且是 非保留表的字段      

explain

select o.id from bigtable b

left join bigtable o

on o.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)

=============总结=============

在关闭cbo的情况下:                             


保留表字段(left的左表)非保留表字段 (left的右表)
on不可以可以
where可以不可以(开启cbo,可以


!!!注意: 

1、对于 Left outer Join ,右侧的表写在 on后面、左侧的表写在 where后面,性能上有提高;

2、对于 Right outer Join,左侧的表写在 on后面、右侧的表写在 where后面,性能上有提高;

3

Full outer Join

案例一:过滤条件写在 where, 且是 保留表的字段     

explain

select o.id from bigtable b

full join bigtable o 

where b.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)


案例二:过滤条件写在 where, 且是 非保留表的字段   

explain

select b.id,o.id from bigtable b

full join bigtable o

where o.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)


案例三:过滤条件写在 on, 且是 保留表的字段        

explain

select o.id from bigtable b

full join bigtable o

on b.id <= 10;

--> 不可以谓词下推(不能在 map 阶段提前过滤)


案例四:过滤条件写在 on, 且是 非保留表的字段      

explain

select o.id from bigtable b

full join bigtable o

on o.id <= 10;

--> 不可以谓词下推(不能在 map 阶段提前过滤)


=============总结=============

1. 如果不开启 cbo,写在 on后面,还是 where后面,都不会谓词下推

2. 如果开启了 cbo,写在 where 可以 谓词下推, 写在 on 不可以 谓词下推


4

Inner Join

案例一:过滤条件写在 where, 且是 保留表的字段     

explain

select o.id from bigtable b

join bigtable o 

where b.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)


案例二:过滤条件写在 where, 且是 非保留表的字段   

explain

select b.id,o.id from bigtable b

join bigtable o

where o.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)


案例三:过滤条件写在 on, 且是 保留表的字段        

explain

select o.id from bigtable b

join bigtable o

on b.id <= 10;

--> 可以谓词下推(能在 map 阶段提前过滤)


案例四:过滤条件写在 on, 且是 非保留表的字段     

explain

select o.id from bigtable b

join bigtable o

on o.id <= 10;

 --> 可以谓词下推(能在 map 阶段提前过滤)


=============总结=============

Inner Join 不管有没有开启cbo,不管写在 on后面 还是 where后面,都会进行谓词下推。


扫码关注我们

微信号|bigdata_story

B站|大数据那些事



浏览 108
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报