1. 程式人生 > >hive中的桶表,以及高效的join方式

hive中的桶表,以及高效的join方式

hive中的join策略 大概可以分為三種

這裡寫圖片描述

前面2種的話都是經常會用到,說下第三種 桶 join

桶(SMB)

物理上,每個桶就是表(或分割槽)目錄裡的一個檔案。
smb的設計是為了解決大表和大表之間的join的。簡單的說下她的思想:大表化成小表,map side join 解決。經典的分而治之的思想。

對一個表或者一個分割槽,可以將其劃分為更細的資料塊,桶。在hive中,分桶的方式採取的是:對列的值進行hash除以桶的數量取餘 ;

為什麼要對資料進行分桶:

  • 桶給表加上了額外的結構,在進行某些查詢的時候可以利用這個結構進行高效的查詢;例如: 對於兩個資料表,某兩列都做了桶劃分,可以使用map端的join高效的完成join(桶和桶之間的join,大大減少了join的次數)。
  • 對於資料取樣更加高效

建立桶劃分的表

CREATE TABLE bucketed_user (id INT) name STRING) 
CLUSTERED BY (id) INTO 4 BUCKETS; 

用CLUSTERED BY (id) INTO 4 BUCKETS 分別指定需要進行分桶的列和需要分桶的數量;

在這裡,我們使用使用者ID來確定如何劃分桶(Hive使用對值進行雜湊並將結果除 以桶的個數取餘數。這樣,任何一桶裡都會有一個隨機的使用者集合(PS:其實也能說是隨機,不是嗎?)。
對於map端連線的情況,兩個表以相同方式劃分桶。處理左邊表內某個桶的 mapper知道右邊表內相匹配的行在對應的桶內。因此,mapper只需要獲取那個桶 (這只是右邊表記憶體儲資料的一小部分)即可進行連線。這一優化方法並不一定要求 兩個表必須桶的個數相同,兩個表的桶個數是倍數關係也可以。

桶中的資料可以根據一個或多個列另外進行排序。由於這樣對每個桶的連線變成了高效的歸併排序(merge-sort), 因此可以進一步提升map端連線的效率。以下語法宣告一個表使其使用排序桶:

CREATE TABLE bucketed_users (id INT, name STRING) 
CLUSTERED BY (id) SORTED BY (id ASC) INTO 4 BUCKETS;

使用tips:
兩個表join的時候,小表不足以放到記憶體中,但是又想用map side join這個時候就要用到bucket Map join。其方法是兩個join表在join key上都做hash bucket,並且把你打算複製的那個(相對)小表的bucket數設定為大表的倍數。這樣資料就會按照join key做hash bucket。小表依然複製到所有節點,Map join的時候,小表的每一組bucket載入成hashtable,與對應的一個大表bucket做區域性join,這樣每次只需要載入部分hashtable就可以了。

ps:map side join其實也是有侷限性的。他要求從表的資料量較小;從表:left join的右表,right join 的左表。

bucket map join
set Hive.optimize.bucketMapjoin = true;
select /*+Mapjoin(a) */count(*)
from Map_join_test a
join Map_join_test b on a.id = b.id;

我們如何保證表中的資料都劃分成桶了呢?把在Hive外生成的資料載入到劃分成 桶的表中,當然是可以的。其實讓Hive來劃分桶更容易。

對於已存在的表

Hive並不檢查資料檔案中的桶是否和表定義中的桶一致(無論是對於桶 的數量或用於劃分桶的列)。如果兩者不匹配,在査詢時可能會碰到錯 誤或未定義的結果。因此,建議讓Hive來進行劃分桶的操作。
相關的操作:
要向分桶表中填充成員,需要將 hive.enforce.bucketing 屬性設定為 true。①這 樣,Hive 就知道用表定義中宣告的數量來建立桶。然後使用 INSERT 命令即可。需要注意的是: clustered by和sorted by不會影響資料的匯入,這意味著,使用者必須自己負責資料如何如何匯入,包括資料的分桶和排序。
‘set hive.enforce.bucketing = true’ 可以自動控制上一輪reduce的數量從而適配bucket的個數,當然,使用者也可以自主設定mapred.reduce.tasks去適配bucket個數,推薦使用’set hive.enforce.bucketing = true’

取樣
SELECT * FROM users 
TABLESAMPLE(BUCKET 1 OUT OF 4 ON rand()); 

一個完整的例子:

建立表


1   create table student(id INT, age INT, name STRING)
2   partitioned by(stat_date STRING)
3   clustered by(id) sorted by(age) into 2 buckets
4   row format delimited fields terminated by ',';
5    
6   create table student1(id INT, age INT, name STRING)
7   partitioned by(stat_date STRING)
8   clustered by(id) sorted by(age) into 2 buckets
9   row format delimited fields terminated by ',';

設定引數

set hive.enforce.bucketing = true;  

插入資料

insert overwrite table student1 partition(stat_date="20120802")
select id,age,name where stat_date="20120802" sort by age;

疑問: 插入的資料沒有按照age 排序,在桶表中會怎麼表現,還是高效的merge-sort模型嗎?
用load data的方式增加進去的方式,不會按照建表的時候制定的排序欄位進行排序,如果是insert 的方式進行資料的插入,是會按照建表的時候制定的欄位進行排序的。
注意
ps:想要使用兩張桶表進行join的時候,兩個表進行交叉的欄位必須是唯一的,不滿足這個條件join出來的結果是錯的。

抽樣

hive> select * from student1 tablesample(bucket 1 out of 2 on id);

Total MapReduce jobs = 1
Launching Job 1 out of 1
.......
OK
4       18      mac     20120802
2       21      ljz     20120802
6       23      symbian 20120802
Time taken: 20.608 seconds

注:tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUT OF y)
y必須是table總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如,table總共分了64份,當y=32時,抽取(64/32=)2個bucket的資料,當y=128時,抽取(64/128=)1/2個bucket的資料。x表示從哪個bucket開始抽取。例如,table總bucket數為32,tablesample(bucket 3 out of 16),表示總共抽取(32/16=)2個bucket的資料,分別為第3個bucket和第(3+16=)19個bucket的資料。

join操作的執行原理

這裡寫圖片描述

相關推薦

hive以及高效join方式

hive中的join策略 大概可以分為三種 前面2種的話都是經常會用到,說下第三種 桶 join 桶(SMB) 物理上,每個桶就是表(或分割槽)目錄裡的一個檔案。 smb的設計是為了解決大表和大表之間的join的。簡單的說下她的思想:大表

Hive對資料庫的操作

在應用Hive之前,首先搭建Hive環境,關於Hive的搭建 參考之前的搭建文件 Hive官方應用文件 資料定義語言 DDL 1、Create Database Hive中資料庫的建立和關係型資料庫類似,用create datebas

hive管理(內部)和外部的區別是什麼及分割槽使用場景

⑴區別: ①Hive建立內部表時(預設建立內部表),會將資料移動到資料倉庫指向的路徑;建立外部表(需要加關鍵字external),僅記錄資料所在的路徑,不對資料的位置做任何改變; ⑵Hive刪除表時,內部表的元資料和資料會被一起刪除,而外部表只刪除元資料,不刪除資料;

Hive建立的各種方式以及區別詳解

          3.新表中會將原表的分割槽當做欄位出現在新表中。> describe formatted mytest_tmp1 ; OK col_name data_type comment # col_name

oracle和mysql資料庫建立之前判斷是否存在如果存在則刪除已有以及在這兩個庫建立

/* Navicat Oracle Data Transfer */ ------------------------------ -- Table structure for `article` -- ---------------------------- --判斷表是否存在,如果存在則刪除 declar

SQL Server查詢資料庫有多少個以及資料庫其餘型別資料統計查詢

sql server 數表: select count(1) from sysobjects where xtype='U' 數檢視: select count(1) from sysobjects where xtype='V' 數儲存過程 select count(1) from sysobjects

SQL:查找被鎖的以及的SQL語句(重點推薦)

內存 結果 dea 但我 使用 相同 以及 serve 釋放 --死鎖檢測 use master Select * from sysprocesses where blocked<>0 --找到SPID exec sp_lock --根據SPI

Ubuntu安裝xampp以及遠程訪問phpmyadmin遇到的問題

deb log alt 空間不足 存儲空間不足 led 存儲空間 註意 blog   安裝到一半提示killed,表示服務器存儲空間不足   phpmyadmin不允許遠程訪問如何解決,在前一篇隨筆已有介紹   設置自動登錄:   首先在根目錄找到config.sample

hive刪除的錯誤Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException

成了 ret jar tor java-5 drop meta org -c hive使用drop table 表名刪除表時報錯,return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException

通過數據庫使用 MyEclipse2017的反向生成工具-->hibernate反轉引擎引擎(MyEclipse2017自帶的插件) 來反轉生成實體類和對應的映射文件

需要 ria sdn http rap div aci radi 工具 Java視圖 1、在MyEclipse中,Java視圖下,新建一個普通的java project,新建該項目的目的是:用來接收反轉引擎生成的實體類和對應的映射文件。 2、在項目上右鍵 -->

Vue-cli使用vConsole以及設定JS連續點選控制vConsole按鈕顯隱功能實現

一、vue-cli腳手架中搭建的專案引入vConsole除錯 1.首先npm安裝,大家都懂的。 npm install vconsole 2.在合適的地方新建一個檔案vconsole.js,內容如下: import Vconsole from 'vconsole' let vConso

Vue-cli使用vConsole以及設置JS連續點擊控制vConsole按鈕顯隱功能實現

vco from main date export lse 發包 操作 前端開發 一、vue-cli腳手架中搭建的項目引入vConsole調試 1.首先npm安裝,大家都懂的。 npm install vconsole 2.在合適的地方新建一個文件vconsole.js

在STS(Spring Tool Suite)配置Maven以及配置不成功的解決方案

Spring Tool Suite  Spring 專案快速開發的工具集合,簡稱sts。 主要用於快速的開發Spring專案,我們不用再去編輯繁瑣的xml配置檔案,而是由工具自動生成。   STS下載 1.可自行到官網下載,選擇需要版本下載 2.ST

圖文詳解Java的servlet以及servlet使用到的關鍵技術

Servlet是Java中實現動態網頁的技術: 如果有想學習java的程式設計師,可來我們的java學習扣qun:79979,2590免費送java的視訊教程噢!小編是一名5年java開發經驗的全棧工程師,整理了一份適合18年學習的java乾貨,送給每一位想學的小夥伴,歡迎大家一起學習哦。

資料結構 線性佇列演算法之間的聯絡與區別

一。連結串列為什麼需要         在程式中,經常需要將一種(通常是同為某個型別的)資料元素作為整體管理和使用,需要建立這種元素組,用變數記錄他們,傳進傳出函式等。一組元素可能發生變化(像增加或刪除元素。)      

cookie,session 的概念以及在django的用法以及cbv裝飾器用法

cookie的由來: 大家都知道HTTP協議是無狀態的。 無狀態的意思是每次請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求都無直接關係,它不會受前面的請求響應情況直接影響,也不會直接影響後面的請求響應情況。 一句有意思的話來描述就是人生只如初見,對伺服器來說,每次的請求都是全新的。 狀態可

【圖文詳細 】HDFS面試題:介紹HadoopRPC協議以及底層用什麼框架封裝的

用於將使用者請求中的引數或者應答轉換成位元組流以便跨機傳輸。 函式呼叫層:函式呼叫層主要功能是:定位要呼叫的函式,並執行該函式,Hadoop採用了java的反射機制和動態代理實現了函式的呼叫。 網路傳輸層:網路傳輸層描述了Client和Server之間訊息的傳輸方式,Hadoop採用了基

多執行緒CountDownLatch的含義以及join的區別

任何執行緒,通常是應用程式的主執行緒,呼叫CountDownLatch.await()將等到計數達到零或被另一個執行緒中斷。所有其他執行緒都需要CountDownLatch.countDown()在完成或準備好後通過呼叫來倒計時。 一旦計數達到零,等待執行緒就會繼續。其中一

通過資料庫使用 MyEclipse2017的反向生成工具-->hibernate反轉引擎引擎(MyEclipse2017自帶的外掛) 來反轉生成實體類和對應的對映檔案

Java檢視 1、在MyEclipse中,Java檢視下,新建一個普通的java project,新建該專案的目的是:用來接收反轉引擎生成的實體類和對應的對映檔案。 2、在專案上右鍵 --> Configure Facets... --> Install Hibernate Facet   

C++霧風景12:聊聊C++的Mutex以及拯救生產力的Boost

筆者近期在工作之中程式設計實現一個Cache結構的封裝,需要使用到C++之中的互斥量Mutex,於是花了一些時間進行了調研。(結果對C++標準庫很是絕望....)最終還是通過利用了Boost庫的shared_mutex解決了問題。借這個機會來聊聊在C++之中的多執行緒程式設計的一些“坑”。 1.C++多執