當前位置:編程學習大全網 - 編程語言 - HiveHive Join 介紹

HiveHive Join 介紹

[TOC]

Hive 中的 Join 只支持等值 Join,也就是說 Join on 中的 on 裏面表之間連接條件只能是 = ,不能是 <,> 等符號。此外,on中的等值連接之間只能是 and,不能是or。

Hive 執行引擎會將 HQL “翻譯” 成為map-reduce 任務,在執行表的 Join 操作時,如果多個表中每個表都使用同壹個列進行連接(出現在 Join on 子句中),則只會生成壹個 MR Job:

三個表 a、b、c 都分別使用了同壹個字段進行連接,亦即同壹個字段同時出現在兩個 Join 子句中,從而只生成壹個 MR Job。

如果多表中,其中存在壹個表使用了至少 2 個字段進行連接(同壹個表的至少2個列出現在 Join 子句中),則會至少生成 2 個MR Job:

三個表基於 2 個字段進行連接,這兩個字段 b.key1 和 b.key2 同時出現在 b 表中。連接的過程是這樣的:首先 a 和 b 表基於a.key 和 b.key1 進行連接,對應著第壹個 MR Job;表 a 和 b 連接的結果,再和 c 進行連接,對應著第二個 MR Job。

這是因為 Map 輸出時候以 Join on 條件中的列為 key,如果 Join 有多個關聯鍵,則以這些關聯鍵的組合作為 key,Map 根據 Key 分發數據給 Reduce 端,具體的 Join 是在 Reduce 操作中完成,因此,如果多表基於不同的列做 Join,則無法在壹輪 MR 任務中將所有相關數據 shuffle 到同壹個 Reduce 操作中。

Hive 支持常用的 SQL Join 語句,例如內連接、左外連接、右外連接以及 Hive 獨有的 map 端連接。其中 map 端連接是用於優化 Hive 連接查詢的壹個重要技巧。

先準備三張表。

employee員工表:

dept部門表:

薪水表:

多張表進行內連接操作時,只有所有表中與 on 條件中相匹配的數據才會顯示,類似取交集。

JOIN 操作符 左邊表中符合 where 條件的所有記錄都會被保留 ,JOIN 操作符右邊表中如果沒有符合 on 後面連接條件的記錄,則從右邊表中選出的列為NULL,如果沒有 where 條件,則左邊表中的記錄都被保留。

標準查詢關鍵字執行順序為 from->on->where->group by->having->order by ,on 是先對表進行篩選後再關聯的,left 關聯則 on 只對右表有效,左表都要選出來。

對於大量的數據,在編寫 SQL 時盡量用 where 條件過濾掉不符合條件的數據是有益的。但是對於左外連接和右外連接, where 條件是在 on 條件執行之後才會執行,on 條件會產生壹個臨時表,where 條件是對這個臨時表進行過濾

因此為了優化 Hive SQL 執行的效率, 在需要使用外連接的場景,如果是要條件查詢後才連接應該把查詢件放置於 on 後,如果是想再連接完畢後才篩選就應把條件放置於 where 後面,對主表的篩選要用 where 條件

特別要註意的是,如果是需要對主表過濾之後再和從表做左關聯,最好將主表寫成子查詢的形式,可以減少主表的數據量

RIGHT OUTER JOIN,與 LEFT OUTER JOIN 相對, JOIN 操作符右邊表中符合where 條件的所有記錄都會被保留 ,JOIN 操作符左邊表中如果沒有符合 on 後面連接條件的記錄,則從左邊表中選出的列為 NULL。

保留滿足 where 條件的兩個表的數據,類似並集,沒有符合連接條件的字段使用 NULL 填充。

以 LEFT SEMI JOIN 關鍵字前面的表為主表,返回主表的 KEY 也在副表中的記錄。在早期的 Hive 版本中,不支持標準 SQL 中的 IN 或 EXISTS 的功能,可以使用LEFT SEMI JOIN 實現類似的功能。

需要強調的是:

笛卡爾積是壹種連接,表示左邊表的行數乘以右邊表的行數。

Hive中的 Join 可分為 Common Join(Reduce 階段完成 join)和 Map Join(Map 階段完成 join)。

如果不指定 Map Join 或者不符合 Map Join 的條件,那麽 Hive 解析器會默認把執行 Common Join,即在 Reduce 階段完成 join。整個過程包含 Map、Shuffle、Reduce 階段。

以下面 HQL 為例,圖解其過程:

Map Join 通常用於壹個很小的表和壹個大表進行 join 的場景,具體小表有多小,由參數 hive.mapjoin.smalltable.filesize 來決定,該參數表示小表的總大小,默認值為 25000000 字節,即 25M。

Hive 0.7 之前,需要使用 hint 提示 / + mapjoin(table) / 才會執行Map Join,否則執行 Common Join,但在 0.7 版本之後,默認自動會轉換 Map Join,由參數hive.auto.convert.join 來控制,默認為 true。

如上圖中的流程, 首先Task A 在客戶端本地執行,負責掃描小表 b 的數據,將其轉換成壹個 HashTable 的數據結構,並寫入本地的文件中,之後將該文件加載到DistributeCache 中。

接下來是 Task B,該任務是壹個沒有 Reduce 的 MR,啟動 MapTasks 掃描大表 a,在 Map 階段,根據 a 的每壹條記錄去和 DistributeCache 中 b 表對應的 HashTable 關聯,並直接輸出結果。

由於 MapJoin 沒有 Reduce,所以由 Map 直接輸出結果文件,有多少個 Map Task,就有多少個結果文件。

Map Join 效率比 Common Join 效率好,但總會有“小表”條件不滿足的時候。這就需要 bucket map join 了。

Bucket map join 需要待連接的兩個表在連接字段上進行分桶(每個分桶對應hdfs上的壹個文件),而且小表的桶數需要時大表桶數的倍數。

建立分桶表的例子:

這樣,my_user 表就對應 32 個桶,數據根據 uid 的 hash value 與32 取余,然後被分發導不同的桶中。

如果兩個表在連接字段上分桶,則可以執行 bucket map join 了,具體的:

對於 bucket map join 中的兩個表,如果每個桶內分區字段也是有序的,則還可以進行 sort merge bucket map join。

建表語句為:

這樣壹來當兩邊 bucket 要做局部 join 的時候,只需要用類似 merge sort 算法中的 merge 操作壹樣把兩個 bucket 順序遍歷壹遍即可完成,小表的數據可以每次只讀取壹部分,然後還是用大表壹行壹行的去匹配,這樣的join 沒有限制內存的大小. 並且也可以執行全外連接。

進行sort merge bucket map join時,需要設置的屬性為:

Join 的過程中,Map 結束之後,會將相同的 Key 的數據 shuffle 到同壹個 Reduce中,如果數據分布均勻的話,每個Reduce 處理的數據量大體上是比較均衡的,但是若明顯存在數據傾斜的時候,會出現某些 Reducer 處理的數據量過大,從而使得該節點的處理時間過長,成為瓶頸。

大表與大表關聯,如果其中壹張表的多是空值或者 0 比較多,容易 shuffle 給壹個reduce,造成運行慢。

這種情況可以對異常值賦壹個隨機值來分散 key,均勻分配給多個 reduce 去執行,比如:

當 key 值都是有效值時,解決辦法為:

設置以下參數:

Hive 在運行的時候無法判斷哪個 key 會產生傾斜,所以使用 hive.skewjoin.key 參數控制傾斜的閾值,如果超過這個值,新的值會發送給那些還沒有達到的 reduce,壹般可以設置成待處理的總記錄數/reduce 個數的 2-4 倍。

1. Hive基礎二(join原理和機制,join的幾種類型,數據傾斜簡單處理)

2. Hive:JOIN及JOIN優化

3. hive中關於常見數據傾斜的處理

  • 上一篇:9月計算機二級考試WEB試題
  • 下一篇:無錫貝斯特精機股份有限公司怎麽樣?
  • copyright 2024編程學習大全網