hive引入partition和bucket的概念,中文翻譯分別為分割槽和桶(我覺的不是很合適,但是網上基本都是這麼翻譯,暫時用這個吧),這兩個概念都是把資料劃分成塊,分割槽是粗粒度的劃分桶是細粒度的劃分,這樣做為了可以讓查詢發生在小範圍的資料上以提高效率。
[b]分割槽的作用:使用分割槽可以加快資料分片的查詢速度。
桶的作用:(1)獲得更高效的查詢處理效率,桶為表加上了額外的結構。
(2)"取樣"更高效。在處理大規模資料集時,在開發和修改查詢階段,如果能在資料集的一小部分資料上試進行查詢,會帶來很多方便。[/b]
首先介紹分割槽的概念,還是先來個例子看下如果建立分割槽表:
create table logs_partition(ts bigint,line string) --ts timestamp line 每一行日誌
partitioned by (dt string,country string) -- 分割槽列 dt 日誌產生日期
建立分割槽表需要在定義表的時候宣告分割槽列,這個分割槽列是個比較有意思的東西下面來看看,向表中匯入資料:
load data local inpath 'input/hive/partitions/file1'
into table logs_partition
partition(dt='2001-01-01',country='gb');
.......
-- 看下表的結構
hive> desc logs_partition;
okts bigint none
line string none
dt string none
country string none
# partition information
# col_name data_type comment
dt string none
country string none
time taken: 0.265 seconds, fetched: 10 row(s)
檢視乙個表的所有分割槽
hive> show partitions logs_partition;
okdt=2001-01-01/country=gb
dt=2001-01-01/country=us
dt=2001-01-02/country=gb
dt=2001-01-02/country=us
time taken: 0.186 seconds, fetched: 4 row(s)
匯入完資料後看下hive資料倉儲表logs_partition下的檔案目錄結構
/user/hive/warehouse/logs_partition
screenshot from 2013-10-10 17:46:25
[b]看到了吧分割槽列都成了目錄了,這樣查詢的時候就會定位到某個目錄下而大大提高了查詢效率,在檢視表結構的時候分割槽列跟其他列並無區別,[/b]看個查詢語句:
select ts, dt, line
from logs
where country='gb';
1 2001-01-01 log line 1
2 2001-01-01 log line 2
4 2001-01-02 log line 4
time taken: 36.316 seconds, fetched: 3 row(s)
這個查詢只會查詢file1, file2, file4這三個檔案還有乙個有趣的問題就是,檢視下資料檔案fieldx
裡面都只包含兩列ts和line並不包含dt和country這兩個分割槽列,但是從查詢結果看分割槽列和非分割槽列並無差別,實際上分割槽列都是從資料倉儲的分割槽目錄名得來的。
接下來說說桶,桶是更為細粒度的資料範圍劃分,它能使一些特定的查詢效率更高,比如對於具有相同的桶劃分並且jion的列剛好就是在桶裡的連線查詢,還有就是示例資料,對於乙個龐大的資料集我們經常需要拿出來一小部分作為樣例,然後在樣例上驗證我們的查詢,優化我們的程式。
下面看看如何建立帶桶的表
create table bucket_user (id int,name string)
clustered by (id) into 4 buckets;
關鍵字clustered宣告劃分桶的列和桶的個數,這裡以使用者的id來劃分桶,劃分4個桶。
以下為了簡便劃分桶的列簡稱為桶列
hive會計算桶列的hash值再以桶的個數取模來計算某條記錄屬於那個桶
向這種帶桶的表裡面匯入資料有兩種方式,一種是外部生成的資料匯入到桶表,一種是利用hive來幫助你生成桶表資料
由於hive在load資料的時候不能檢查資料檔案的格式與桶的定義是否匹配,如果不匹配在查詢的時候就會報錯,所以最好還是讓hive來幫你生成資料,簡單來說就是利用現有的表的資料匯入到新定義的帶有桶的表中,下面來看看:
已經存在的表:
hive> select * from users;
ok0 nat
2 joe
3 kay
4 ann
hive> set hive.enforce.bucketing=true --必須設定這個資料,hive才會按照你設定的桶的個數去生成資料
下面把user的資料匯入到bucketed_users中
insert overwrite table bucketed-users
select * from users;
然後見證奇蹟的時刻:
hive> dfs -ls /user/hive/warehouse/bucketed_users;
-rw-r--r-- 1 root supergroup 12 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000000_0
-rw-r--r-- 1 root supergroup 0 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000001_0
-rw-r--r-- 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000002_0
-rw-r--r-- 1 root supergroup 6 2013-10-10 18:48 /user/hive/warehouse/bucketed_users/000003_0
hive> dfs -cat /user/hive/warehouse/bucketed_users/000000_0;
0nat
4ann
下面來看看利用bucket來對示例資料進行查詢
---帶桶的表
select * from bucketed_users
tablesample(bucket 1 out of 4 on id);
---不帶桶的表
select * from users
tablesample(bucket 1 out of 4 on rand());
tablesample的作用就是讓查詢發生在一部分桶上而不是整個資料集上,上面就是查詢4個桶裡面第乙個桶的資料
相對與不帶桶的表這無疑是效率很高的,因為同樣都是需要一小部分資料,但是不帶桶的表需要使用rand()函式,需要在整個資料集上檢索。
hive學習 分割槽 分桶和索引
分割槽是以字段的形式在表結構中存在,通過describe table命令可以檢視到字段存在,但是該字段不存放實際的資料內容,僅僅是分割槽的表示 偽列 1 靜態分割槽 create table if not exists sopdm.wyp2 id int,name string,tel string...
Hive的分割槽 分桶 索引
一 分割槽 mr的分割槽 是將資料按照一定的邏輯進行查分,劃分為不同的區域,這個區域的資料將會給指定的reduce。hive的分割槽 對錶劃分成幾個區域,通過分類把不同型別的資料放到不同的目錄下。分割槽表與普通表相比它的優勢和劣勢 優勢 和普通表相比,當按照分割槽條件進行過濾的時候分割槽表會比普通表...
Hive分割槽 分桶
create table t user partition id int name string partitioned by country string row format delimited fields terminated by load data local inpath root h...