hive的分區概念,相信大家都非常了解了。通過將數據放在hdfs不同的文件目錄下,查表時,只掃描對應分區下的數據,避免了全表掃描。
提升了查詢效率。
關於hive分區,我們還會用到多級分區、動態分區、混合分區,這些概念是什么含義,又該在何時使用呢?
靜態分區
先說下靜態分區。靜態分區就是人為指定分區名。向分區插入數據的時候也要寫明寫入哪個分區。
我們給出建表,和插入數據的示例代碼:
建表語句:
DROP TABLE IF EXISTS ods.employee; CREATE TABLE IF NOT EXISTS ods.employee( xjson STRING ) COMMENT '員工表' PARTITIONED BY (province,city) ROW FORMAT DELIMITED |
數據插入語句:
ALTER TABLE ods.employee DROP IF EXISTS PARTITION (`province`=${province},`city`=${city}); ALTER TABLE ods.employee ADD IF NOT EXISTS PARTITION (`province`=${province},`city`=${city}) INSERT OVERWRITE TABLE FINAL.employee PARTITION(`province`=${province},`city`=${city}) SELECT xjson FROM ods.employee_full WHERE `province`=${province},`city`=${city}; |
tips:
1.進行drop分區,是為了方便重跑。不去手動增加partition也是可以的。
2.寫入時用overwrite也是為了方便使用腳本重跑。
2.province`=${province},`city`=${city} 是為了使用調度執行時,可以穿入不同的參數。避免重復的代碼。
需要注意的是,
1.我們指定分區的那一列 dt 可以看做hive的偽列,雖然在select查詢時,會展現在數據的最后,但不會真正出現在數據中。
2.dt也不應該出現在表的某一列名中,否則會報錯。
動態分區
動態分區是相對靜態分區的。
動態分區可以根據我們指定的某個字段的值,將數據動態寫入對應的分區。
我們指定的字段中每有一個取值,就會生成一個分區。
建表語句示例:
create table ods.employee like ods.employee_tmp; 必配參數: set hive.exec.dynamici.partition=true; --開啟動態分區,默認是false 可配置參數: set mapreduce.job.name=ods.ods_mysql_sale_sale_detail; --設置執行任務名稱 set hive.merge.mapredfiles = true; --Map-Reduce的任務結束時合並小文件 set hive.exec.dynamic.partition.mode=nonstrict; --開啟允許所有分區都是動態的,否則必須要有靜態分區才能使用。 set hive.exec.max.dynamic.partitions.pernode=100000;--缺省值是100,指每個mapper或reducer可以創建的最大動態分區個數,如果某個mapper或者reducerchangshi 創建大於這個數目的分區,那么就會報錯。 set hive.exec.max.dynamic.partitions =100000;--缺省值是+1000,指的是一個動態分區創建語句可以創建的最大分區數目,如果超過這個數目就會拋出一個致命錯誤。 set hive.exec.max.created.files =1000000; --缺省值是100000,全局 可以創建的最大文件個數。 |
tips:hive建表時,like關鍵字可以創建結構完全相同的表。
數據插入語句示例:
insert overwrite tableods.employee partition(province,city) select name, salary, subordinates, deductions, address, province, city from ods.employee_tmp t |
hive 會根據最后兩個列,決定數據最終寫入哪個分區中。
混合分區
了解了靜態分區與動態分區。讓我們學習下混合分區。
假設這樣一種情況,我們使用了動態分區,一張表的某個字段的值,決定了另一張表的分區,
如果由於存在臟數據,或人為指定字段錯誤,就會在另一張表產生茫茫多的分區。
hive的分區數據也是元數據的一部分,由hdfs的namenode管理,hive啟動后,會緩存在內存中。
一級分區過多會影響集群性能。
為了避免這種情況,就該使用混合分區。
混合分區的概念並不復雜,就是混合了動態分區和靜態分區。且靜態分區應該放到動態分區的前面。
插入數據時,第一級分區寫死,第二級分區使用靜態分區。這樣就有效控制了由於分區過多,
導致文件名過多,影響hdfs性能的問題。
建表語句示例和動態分區一樣,只是在數據插入時會體現出混合分區。
那么,看下數據插入語句:
insert overwrite tableods.employee partition(province='zhejiang',city) select name, salary, subordinates, deductions, address, province, city from ods.employee_tmp t |
代碼的第一行體現了混合分區的用法。
多級分區
多級分區,其實我們在上面一直在使用。這里再提一下,
就是第一級分區下,增加第二級分區。對應hdfs就是嵌套的文件夾。