2013-05-03 32 views
0

我有3個小表:smallTable0,smallTable1smallTable3。他們都有不到100行和相同的模式。我也有3個大表:largeTable0largeTable1largeTable3。全部有超過1M行,具有相同的模式,與小表共享id列,除id以外的其他分區(如果分區很重要,我懷疑它不會)。蜂巢不MapJoin對兩個大表的聯盟小表

設置hive.auto.convert.join=true後,有下列情形導致MapJoin,符合市場預期:

  • 加入smallTable0smallTable1
  • 加入smallTable0largeTable0
  • 加入smallTable0smallTable1 UNION ALL smallTable2

以下情況不會導致在一個MapJoin,如預期的那樣:

  • 加入largeTable0反對任何事情。
  • 加入smallTable0反對任何與hive.auto.convert.join=false

不料但是,下面的情況下也不會導致MapJoin:

  • 加入smallTable0largeTable0 UNION ALL largeTable1

準確的查詢是如下:

SELECT * FROM smallTable0 s 
JOIN (
    SELECT * FROM (
    SELECT * FROM largeTable0 
    UNION ALL 
    SELECT * FROM largeTable1 
) x 
) l 
    ON s.id = l.id; 

它運行良好,但使用通用連接而不是MapJoin,導致性能下降。創建代表largeTable0 UNION ALL largeTable1的視圖不能解決問題。我確定創建一個表largetTable0 UNION ALL largeTable1可以解決問題,但重複這麼多的數據,然後保持同步是不可取的。

聯盟運營商的源代碼(here)有一個評論,我覺得有點神祕。

/** 
* Union operators are not allowed either before or after a explicit mapjoin hint. 
* Note that, the same query would just work without the mapjoin hint (by setting 
* hive.auto.convert.join to true). 
**/ 
@Override 
public boolean opAllowedBeforeMapJoin() { 
    return false; 
} 

@Override 
public boolean opAllowedAfterMapJoin() { 
    return false; 
} 

這似乎表明,UNION操作是不允許有一個明確的暗示MapJoin,但是,聯盟允許操作員與活動開始hive.auto.convert.join結果MapJoins。不過,我不明白爲什麼會允許另一個被禁止。除非「僅僅工作」意味着查詢將「工作」,而不是用MapJoin。但是,如果是這種情況,我預計會加入smallTable0smallTable1 UNION ALL smallTable2以產生一個通用連接。

由於Hive中的錯誤,我的代碼中的錯誤,Hive中的缺失功能或者我的誤解,這是否是奇怪的行爲?

回答

1

您可以指定Hive在連接期間處理表。我總是指定MAPJOINSTREAMTABLE如果我知道一個小表是否適合連接,或者是應該流式傳輸給其他人的非常大的表。

例如

SELECT /*+ MAPJOIN(smalltable0) */ * FROM smallTable0 s