一、背景

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

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

二、表的分类

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

2.1 Preserved Row table:保留表

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

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

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

2.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值保留表

2.3 During Join predicate:join中谓词

就是on后面的条件。

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

2.4 After Join predicate:join后谓词

就是where后面的条件。

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

三、关联场景分析

备注:关闭 cbo 优化:set hive.cbo.enable=false

链接:

关联类型

测试场景

测试sql

测试结果

Left outer Join & Right outer Join

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

select o.id from bigtable b

left join bigtable o 

where b.id <= 10;

可以

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

select b.id,o.id from bigtable b

left join bigtable o

where o.id <= 10;

不可以

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

select o.id from bigtable b

left join bigtable o

on b.id <= 10;

不可以

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

select o.id from bigtable b

left join bigtable o

on o.id <= 10;

可以

Full outer Join

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

select o.id from bigtable b

full join bigtable o 

where b.id <= 10;

可以

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

select b.id,o.id from bigtable b

full join bigtable o

where o.id <= 10;

可以

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

select o.id from bigtable b

full join bigtable o

on b.id <= 10;

不可以

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

select o.id from bigtable b

full join bigtable o

on o.id <= 10;

不可以

Inner Join

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

select o.id from bigtable b

join bigtable o 

where b.id <= 10;

可以

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

select b.id,o.id from bigtable b

join bigtable o

where o.id <= 10;

可以

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

select o.id from bigtable b

join bigtable o

on b.id <= 10;

可以

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

select o.id from bigtable b

join bigtable o

on o.id <= 10;

可以

四、总结

4.1 Left outer Join & Right outer Join

保留表字段(left的左表)

非保留表字段 (left的右表)

on

不可以

可以

where

可以

不可以(开启cbo,可以)

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

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

4.2 Full outer Join

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

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

4.3 Inner Join

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

4.4 最终总结

inner join

 

left join

 

right join

 

outer join

 

左表

右表

左表

右表

左表

右表

左表

右表

join中的谓词

Pushed

Pushed

Not Pushed

Pushed

Pushed

Not Pushed

Not Pushed

Not Pushed

join后的谓词

Pushed

Pushed

Pushed

Pushed

Pushed

Pushed

Pushed

Pushed