Hive分桶表及抽樣查詢

抽樣查詢

對於非常大的數據集,用戶不需要全部查詢的結果,只需要一個代表性的查詢結果時,可以通過對錶進行分桶抽樣。

Hive分桶表

先介紹一下Hive桶。
桶是比表或分區更爲細粒度的數據範圍劃分。針對某一列進行桶的組織,對列值哈希,然後除以桶的個數求餘,決定將該條記錄存放到哪個桶中。
好處:
1、獲得更高的查詢處理效率。
2、使抽樣更高效。
創建帶桶的table:

create table bucketed_user(id int ,name string) clustered by (id)  into 4 buckets row format delimited fields terminated by '\t' stored as textfile;

使用CLUSTERED BY子句指定使用哪一個列來劃分桶和要劃分的桶的個數。
對於map端連接的情況,兩個表以相同方式劃分桶。處理左邊表內某個桶的mapper知道右邊表內相匹配的行在哪個對應的桶內。因此,mapper只需要獲取那個桶 (這只是右邊表內存儲數據的一小部分)即可進行連接。這一優化方法並不一定要求兩個表必須具有相同個數的桶,兩個表的桶個數是倍數關係也可以。
創建一個排序桶:

create table bucketed_users(id int ,name string) clustered by (id) sorted by (name) into 4 buckets;

查看目錄,發現已經有了bucketed_users這個目錄

hive> dfs -ls /user/hive/warehouse;
Found 4 items
drwxrwxr-x   - mahao supergroup          0 2016-09-13 22:59 /user/hive/warehouse/bucketed_users
drwxrwxr-x   - mahao supergroup          0 2016-09-12 01:58 /user/hive/warehouse/employees
drwxrwxr-x   - mahao supergroup          0 2016-09-08 20:04 /user/hive/warehouse/src
drwxrwxr-x   - mahao supergroup          0 2016-09-07 22:26 /user/hive/warehouse/test

桶中的數據根據name列進行排序,在對每個桶進行連接時變成了高效的歸併排序。
Hive不檢測數據文件中的桶是否和表定義中的桶一致(桶數或劃分桶的列),如果不匹配,會在查詢時出錯,所以,建議讓Hive來劃分桶的操作。
向表中插入數據

物理上,一個桶就是表(或分區)目錄裏的一個文件。桶對應於MapReduce的輸出文件分區:一個作業產生的桶(輸出文件)和reduce任務個數相同。
在向分桶表加載數據時,需要先

set hive.enforce.bucketing=true;(hive2.0好像沒有這個參數)

這樣Hive就知道用表定義中聲明的數量來創建桶,然後使用INSERT加載數據即可。
先準備一個沒有劃分桶的表users。

hive> select * from users;
OK
1   zhangsan
2   lisi
3   wangwu

向分桶表中插入數據:

INSERT OVERWRITE TABLE bucketed_users SELECT * FROM users;

查看錶結構:

mahao@ubuntu:~$ hadoop fs -ls /user/hive/warehouse/bucketed_users
Found 4 items
-rwxrwxr-x   1 mahao supergroup          0 2016-09-13 23:36 /user/hive/warehouse/bucketed_users/000000_0
-rwxrwxr-x   1 mahao supergroup         11 2016-09-13 23:36 /user/hive/warehouse/bucketed_users/000001_0
-rwxrwxr-x   1 mahao supergroup          7 2016-09-13 23:36 /user/hive/warehouse/bucketed_users/000002_0
-rwxrwxr-x   1 mahao supergroup          9 2016-09-13 23:36 /user/hive/warehouse/bucketed_users/000003_0

發現有四個文件,即四個桶。
查看文件:

mahao@ubuntu:~$ hadoop fs -cat /user/hive/warehouse/bucketed_users/*0_0;
mahao@ubuntu:~$ hadoop fs -cat /user/hive/warehouse/bucketed_users/*1_0;
1zhangsan
mahao@ubuntu:~$ hadoop fs -cat /user/hive/warehouse/bucketed_users/*2_0;
2lisi
mahao@ubuntu:~$ hadoop fs -cat /user/hive/warehouse/bucketed_users/*3_0;
3wangwu

因爲不會顯示分隔符,所以看着就是挨着的。

抽樣查詢

hive>SELECT * FROM bucketed_users TABLESAMPLE(bucket 1 out of 2 on id);
2   lisi

注: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的數據。

發佈了71 篇原創文章 · 獲贊 322 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章