1. 程式人生 > 其它 >謂詞下推

謂詞下推

一、參考地址

  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 from
bigtable 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後面,都會進行謂詞下推