数据仓库(八)---hive的性能优化---hive动态分区

我们在上一篇文章中已经学习了如何进行分区,手动分区。
数据仓库(七)—hive的性能优化—hive的分区和分桶
但是分区之后 再插入数据时,并不会自动的进行分区,而是需要再次手动分区。
关系型数据库(如Oracle)中,对分区表Insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive中也提供了类似的机制,即动态分区(Dynamic Partition),只不过,使用Hive的动态分区,需要进行相应的配置。

分区种类

分区分为两种:
静态分区static partition
动态分区dynamic partition
静态分区和动态分区的区别在于导入数据时,是手动输入分区名称,还是通过数据来判断数据分区。对于大数据批量导入来说,显然采用动态分区更为简单方便。

动态分区配置方法

修改一下hive的默认设置以支持动态分区:

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

其他参数

hive.exec.dynamic.partition
默认值:false
是否开启动态分区功能,默认false关闭。
使用动态分区时候,该参数必须设置成true;

hive.exec.dynamic.partition.mode
默认值:strict
动态分区的模式,默认strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。
一般需要设置为nonstrict

hive.exec.max.dynamic.partitions.pernode
默认值:100
在每个执行MR的节点上,最大可以创建多少个动态分区。
该参数需要根据实际的数据来设定。
比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。

hive.exec.max.dynamic.partitions
默认值:1000
在所有执行MR的节点上,最大一共可以创建多少个动态分区。
同上参数解释。

hive.exec.max.created.files
默认值:100000
整个MR Job中,最大可以创建多少个HDFS文件。
一般默认值足够了,除非你的数据量非常大,需要创建的文件数大于100000,可根据实际情况加以调整。

hive.error.on.empty.partition
默认值:false
当有空分区生成时,是否抛出异常。
一般不需要设置。

实例

静态分区

新建一个静态分区表t_student,把原信息表t_student_info_25根据分区age=25放入分区,也就是说 如果有30多个年龄阶段就需要执行30多次类似的命令。

create table if not exists t_student(id int,name string,tel string) partitioned by(age int)
row format delimited fields terminated by ','
stored as textfile;

–overwrite是覆盖,into是追加

insert into table t_student
partition(age='25')
select id,name,tel,age from t_student_info_25;

动态分区

设置为true表示开启动态分区功能(默认为false)
set hive.exec.dynamic.partition=true;

设置为nonstrict,表示允许所有分区都是动态的(默认为strict)
set hive.exec.dynamic.partition.mode=nonstrict;

insert overwrite是覆盖,insert into是追加

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table t_student
partition(age)
select id,name,tel,age from t_student_info;

注意事项

从原表中select出来的字段顺序需要与分区表的列一致,因为 分区后的表 是把 用来分区的字段放在最后的,如果直接select * 进行insert的话,会导致列不对应。

如果查询出来的数据类型和插入表格对应的列数据类型不一致,将会进行转换,但是不能保证转换一定成功,比如如果查询出来的数据类型为int,插入表格对应的列类型为string,可以通过转换将int类型转换为string类型;但是如果查询出来的数据类型为string,插入表格对应的列类型为int,转换过程可能出现错误,因为字母就不可以转换为int,转换失败的数据将会为NULL。

静态分区和动态分区混合使用

全部DP

INSERT OVERWRITE TABLE t_student PARTITION (time, age)  
SELECT id, name, time, age FROM t_student_info WHERE time is not null and age>10;  

DP/SP结合

INSERT OVERWRITE TABLE t_student PARTITION (time='2018-02-27', age)  
SELECT id, name, time,age FROM t_student_info WHERE time is not null and age>10;  

注意
当SP是DP的子分区时,以下DML会报错,因为分区顺序决定了HDFS中目录的继承关系,这点是无法改变的

INSERT OVERWRITE TABLE t_student PARTITION (time, age = 11)  
SELECT id, name, time,age FROM t_student_info WHERE time is not null and age=11;  

多张表插入

FROM student  
INSERT OVERWRITE TABLE t_student PARTITION (time='2018-02-27', age)  
SELECT id, name, time, age FROM t_student_info WHERE time is not null and age>10  
INSERT OVERWRITE TABLE t_student_12 PARTITION (time='2018-02-27, age=12)  
SELECT id, name, time, age from t_student_info where time is not null and age = 12;  

CTAS
CREATE-AS语句,DP与SP下的CTAS语法稍有不同,因为目标表的schema无法完全的从select语句传递过去。这时需要在create语句中指定partition列

CREATE TABLE t_student (id int, name string) PARTITIONED BY (time string, age int) AS  
SELECT id, name, time, age+1 age1 FROM t_student_info WHERE time is not null and age>10;  

上面展示了DP下的CTAS用法,如果希望在partition列上加一些自己的常量,可以这样做

CREATE TABLE t_student (id int, name string) PARTITIONED BY (time string, age int) AS  
SELECT id, name, "2018-02-27", age+1 age1 FROM t_student_info WHERE time is not null and age>10;  

总结

结果本章学习,我们应该知道了对于那些存在很大数量的二级分区的表,使用动态分区可以非常智能的加载表,而在动静结合使用时需要注意静态分区值必须在动态分区值的前面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张小凡vip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值