hive學習 分割槽 分桶和索引

2021-09-02 12:26:30 字數 4205 閱讀 6361

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...