HIVE默認是靜態分區。但是有時候可能需要動態創建不同的分區,比如商品信息,我想根據它是否在線分成兩個分區,這樣後續如果要取在線商品,就只需要從在線的分區獲取即可。動態分區可以通過下面的設置來打開:
- set hive.exec.dynamic.partition=true;
- set hive.exec.dynamic.partition.mode=nonstrict;
然後代碼裏就可以這麼寫:
- insert overwrite table tbl_name partition(pt, if_online)
- select field1, field2, ..., pt, if_online
- from tbl
- where xxx;
注意輸入字段的最後面必須是動態分區字段。
看一下與靜態分區寫法的區別:
- insert overwrite table tbl_name partition(pt=20121023, if_online=1)
- select field1, field2, ..., fieldn
- from tbl
- where xxx;
動態分區與靜態分區還有一個細微的差別是,靜態分區一 定會創建分區,不管SELECT語句的結果有沒有數據。而動態分區,只有在SELECT結果的記錄數>0的時候,纔會創建分區。因此在不同的業務場景下,可能會選擇不同的方案。
另外使用動態分區時需要注意的比較重要的一點是,動態分區會爲每一個分區分配reduce數。比如說你在腳本上面寫了:set mapred.reduce.tasks=100;
並且有兩個分區:pt, if_online。如果結果集中pt=20121023,if_online=0/1,那麼它就會爲pt=20121023/if_online=0,pt=20121023/if_online=1各分配100個reduce。也就是說,namenode會同時處理200個文件的寫操作。這在分區值很多的情況下,會成爲一個災難,容易直接把namenode給搞掛掉,是非常危險的。因此使用動態分區時,一定要清楚地知道產生的動態分區值,並且合理地設置reduce數量。