2013-11-25 104 views
11

我在蜂巢連接兩個大表(其中一個是超過十億行,一個是大約100萬行),像這樣:蜂巢 - 高效連接兩個表

create table joinedTable as select t1.id, ... from t1 join t2 ON (t1.id = t2.id); 

我已經時段的兩個表同樣的方法,通過將每個id聚類爲100個桶,但查詢仍然需要很長時間。

關於如何加快速度的建議?

回答

13

當您通過連接鍵對數據進行分段處理時,可以使用Bucket Map Join。爲此,一個表中的桶的數量必須是另一個表中的桶的數量的倍數。可以在查詢前執行set hive.optimize.bucketmapjoin=true;來激活它。如果表格不符合條件,Hive將簡單地執行正常的Inner Join。

如果兩個表具有相同數量的存儲桶並且數據按存儲桶密鑰排序,則Hive可以執行更快的排序 - 合併聯接。要激活它,你必須執行以下命令:

set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat; 
set hive.optimize.bucketmapjoin=true; 
set hive.optimize.bucketmapjoin.sortedmerge=true; 

你可以找到不同的某些可視https://cwiki.apache.org/confluence/download/attachments/27362054/Hive+Summit+2011-join.pdf下加入技術。

+0

我會給它一個鏡頭。在Hive中索引是否有幫助?即。如果我通過id爲t1和t2編制索引? – maia

+0

我如何估計要使用多少個桶? – maia

+0

索引不會提高聯接中的性能。它們用於檢索單行,例如在'WHERE id = 123'中。剷鬥是這裏最好的選擇。 –

11

正如我所看到的,答案比@Adrian Lange提供的要複雜一點。

首先,你必須瞭解BucketJoin和排序合併桶加入(SMBJ)之間一個非常重要的區別:

要執行bucketjoin「水桶在一個表中的金額必須是量的倍數如前所述,另外hive.optimize.bucketmapjoin必須設置爲true。
發出加入,配置單元會將其轉換爲bucketjoin如果發生上述情況但是請注意,配置單元不會強制執行分配!這意味着創建表分區是不夠的,因爲表實際上被分配到指定數量的桶中,因爲除非hive.enforce.bucketing設置爲true,否則配置單元不會執行此操作(這意味着實際上桶的數量由在查詢的最後階段將數據插入表中的減速器的數量)。
從性能方面來說,請注意當使用bucketjoin a 單個任務在映射器訪問它並進行連接之前將「較小」表讀入分佈式緩存中 - 此階段可能會非常長當你的桌子有100米左右時,效果不佳!
之後,加入過程與在減速器中進行的常規加入相同。

要執行SMBJ兩個表必須有水桶完全相同的量,在同一列,除了這些列排序,以設置hive.optimize.bucketmapjoin.sortedmerge爲true。
與之前的優化一樣,Hive並沒有強制執行分段和排序,而是假定您確保表格實際是分段和排序的(不僅按照定義,而且通過設置hive.enforce.sorting或在插入時手動排序數據) - 這是非常重要的,因爲它可能導致在兩種情況下的錯誤結果
作爲從服務表現方面,這種優化的方式更有效,原因如下:

  1. 每個映射器讀取兩個水桶,有聯接正在執行對分佈式緩存加載沒有單一的任務爭
  2. 是合併 - 排序連接,因爲數據已經被排序,效率更高。

請注意以下事項:

    在這兩種情況下
  • set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
    應執行
  • 在這兩種情況下/*+ MAPJOIN(b) */應在查詢(可應用select後馬上其中b是小表)
  • 有多少個水桶?
    這應該從這個角度來看:考慮應該嚴格適用於更大的表格,因爲它從這個方向有更多的影響,後者的配置將作爲必須應用到更小的表格。我認爲根據經驗,每個桶應該包含1到3個塊,可能在2個塊附近。所以如果你的塊大小是256MB,它對我來說合理的是在大表中的每個桶中有〜512MB的數據,所以這成爲一個簡單的分割問題。

另外,不要忘記,這些優化本身並不總能保證更快的查詢時間。
假設您選擇執行SMBJ,這會增加在運行聯接之前對2個表進行排序的成本 - 因此您運行查詢的次數越少,您將爲此排序階段「付費」的次數越少。

有時候,簡單的連接會導致最佳的性能,上述優化都不會起到幫助作用,您將不得不在應用程序/邏輯級別或通過調整MapReduce/Hive設置(如內存使用情況)來優化常規連接過程/並行等

0

我不認爲它必須的標準「一個表中的桶的數量必須是另一個表中桶的數量的倍數」,對於地圖桶連接,我們可以有相同數量的桶也。