一文詳解Hive的謂詞下推

謂詞,是指用來描述或判斷客體性質(zhì)、特征或客體之間關(guān)系的詞項(xiàng)。在SQL中即返回值為布爾值的函數(shù)。
謂詞下推,在Hive中叫Predicate Pushdown,含義是指在不影響結(jié)果的前提下,盡量將過濾條件提前執(zhí)行,使得最后參與join的表的數(shù)據(jù)量更小。謂詞下推后,過濾條件將在map端提前執(zhí)行,減少map端輸出,降低了數(shù)據(jù)傳輸IO,節(jié)約資源,提升性能。在Hive中通過配置hive.optimize.ppd參數(shù)為true,開啟謂詞下推,默認(rèn)為開啟狀態(tài)。
表的分類
首先定義一下參與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后謂詞
Left outer Join & Right outer Join
!?。y試時(shí),關(guān)閉 cbo 優(yōu)化: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 階段提前過濾)
=============總結(jié)=============
在關(guān)閉cbo的情況下:
| 保留表字段(left的左表) | 非保留表字段 (left的右表) | |
| on | 不可以 | 可以 |
| where | 可以 | 不可以(開啟cbo,可以) |
?。?!注意:
1、對于 Left outer Join ,右側(cè)的表寫在 on后面、左側(cè)的表寫在 where后面,性能上有提高;
2、對于 Right outer Join,左側(cè)的表寫在 on后面、右側(cè)的表寫在 where后面,性能上有提高;
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 階段提前過濾)
=============總結(jié)=============
1. 如果不開啟 cbo,寫在 on后面,還是 where后面,都不會(huì)謂詞下推
2. 如果開啟了 cbo,寫在 where 可以 謂詞下推, 寫在 on 不可以 謂詞下推
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 階段提前過濾)
=============總結(jié)=============
Inner Join 不管有沒有開啟cbo,不管寫在 on后面 還是 where后面,都會(huì)進(jìn)行謂詞下推。


掃碼關(guān)注我們
微信號|bigdata_story
B站|大數(shù)據(jù)那些事
