謂詞下推
一、參考地址
1)官網參考:https://cwiki.apache.org/confluence/display/Hive/OuterJoinBehavior
2)cbo參考:https://cwiki.apache.org/confluence/display/Hive/Cost-based+optimization+in+Hive
二、分析
謂詞下推:就是在join之前的 mr 任務的 map 階段提前對錶進行過濾優化,使得最後參與 join 的表的資料量更小
首先定義了join的四種類型的表:
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後謂詞
三、測試
測試時,關閉 cbo 優化:set hive.cbo.enable=false
3.1 Left outer Join & Right outer Join
案例一:過濾條件寫在 where, 且是 保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id from bigtable b left join bigtable o where b.id <= 10;
案例二:過濾條件寫在 where, 且是 非保留表的欄位 --> 不可以謂詞下推(不能在 map 階段提前過濾)
注意: 關閉cbo去測 set hive.cbo.enable=false,如果開啟了cbo,會自動優化成可以謂詞下推;
explain select b.id,o.id from bigtable b left join bigtable o where o.id <= 10;
案例三:過濾條件寫在 on, 且是 保留表的欄位 --> 不可以謂詞下推(不能在 map 階段提前過濾)
explain select o.id from bigtable b left join bigtable o on b.id <= 10;
案例四:過濾條件寫在 on, 且是 非保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id frombigtable b left join bigtable o on o.id <= 10;
總結:
在關閉cbo的情況下
保留表字段(left的左表) | 非保留表字段 (left的右表) | |
on | 不可以 | 可以 |
where | 可以 | 不可以(開啟cbo,可以) |
1、對於 Left outer Join ,右側的表寫在 on後面、左側的表寫在 where後面,效能上有提高;
2、對於 Right outer Join,左側的表寫在 on後面、右側的表寫在 where後面,效能上有提高;
3.2 Full outer Join
案例一:過濾條件寫在 where, 且是 保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id from bigtable b full join bigtable o where b.id <= 10;
案例二:過濾條件寫在 where, 且是 非保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select b.id,o.id from bigtable b full join bigtable o where o.id <= 10;
案例三:過濾條件寫在 on, 且是 保留表的欄位 --> 不可以謂詞下推(不能在 map 階段提前過濾)
explain select o.id from bigtable b full join bigtable o on b.id <= 10;
案例四:過濾條件寫在 on, 且是 非保留表的欄位 --> 不可以謂詞下推(不能在 map 階段提前過濾)
explain select o.id from bigtable b full join bigtable o on o.id <= 10;
總結:
Full outer Join情況下
如果不開啟 cbo,寫在 on後面,還是 where後面,都不會謂詞下推
如果開啟了 cbo,寫在 where 可以 謂詞下推, 寫在 on 不可以 謂詞下推
3.3 Inner Join
案例一:過濾條件寫在 where, 且是 保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id from bigtable b join bigtable o where b.id <= 10;
案例二:過濾條件寫在 where, 且是 非保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select b.id,o.id from bigtable b join bigtable o where o.id <= 10;
案例三:過濾條件寫在 on, 且是 保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id from bigtable b join bigtable o on b.id <= 10;
案例四:過濾條件寫在 on, 且是 非保留表的欄位 --> 可以謂詞下推(能在 map 階段提前過濾)
explain select o.id from bigtable b join bigtable o on o.id <= 10;
總結: Inner Join 不管有沒有開啟cbo,不管寫在 on後面 還是 where後面,都會進行謂詞下推