分區是在處理大型事實表時常用的方法。分區的好處在於縮小查詢掃描範圍,從而提高速度。分區分爲兩種:靜態分區static partition和動態分區dynamic partition。靜態分區和動態分區的區別在於導入數據時,是手動輸入分區名稱,還是通過數據來判斷數據分區。對於大數據批量導入來說,顯然採用動態分區更爲簡單方便。
對現存hive表的分區
首先,新建一張我們需要的分區以後的表create table like ‘origin’
然後,我們修改一下hive的默認設置以支持動態分區:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
第二步僅在你僅使用動態分區字段做分區索引時。
然後用hive的insert命令進行插入操作。注意,除了所有列外,需要將分區的動態字段跟在後面。
INSERT OVERWRITE TABLE target PARTITION (dt)
SELECT id,user_id,app_id,time,ip,substr(time,0,10) FROM origin
可以看到,動態分區的字段支持函數操作。
這樣,我們得到了一張分區後的hive大表。
在hive中,有時候會希望根據輸入的key,把結果自動輸出到不同的目錄中,這可以通過動態分區來實現,就是把每一個key當作一個分區,代碼示例如下:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.dynamic.partitions.pernode=50000;
set hive.exec.dynamic.partitions.partitions=50000;
set hive.exec.max.created.files=500000;
set mapred.reduce.tasks =20000;
set hive.merge.mapfiles=true;
drop table itemset;
create table itemset(
auctions string)
partitioned by (category_id string)
row format delimited
fields terminated by '\t'
stored as textfile
location '/data/itemset';
insert overwrite table itemset partition(category_id)
select auctions, category_id from source_table distribute by category_id;
注意首先需要在hive語句中設置允許動態分區。即:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
但是這還不夠,在動態分區有可能很大的情況下,還需要其他的調整:
hive.exec.dynamic.partitions.pernode 參數指的是每個節點上能夠生成的最大分區,這個在最壞情況下應該是跟最大分區一樣的值
hive.exec.dynamic.partitions.partitions 參數指的是總共的最大的動態分區數
hive.exec.max.created.files 參數指的是能夠創建的最多文件數(分區一多,文件必然就多了…)
最後要注意的是select語句中要把distribute的key也select出來