什么动态分区,动态分区好处
动态分区是分区在数据插入的时候,根据某一列的列值动态生成.
往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。
静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。
准备工作
准备数据
order_created.txt
[root@zjj101 soft]# cat order_created.txt
10703007267488 2014-05-01 06:01:12.334+01
10101043505096 2014-05-01 07:28:12.342+01
10103043509747 2014-05-02 07:50:12.33+01
10103043501575 2014-05-02 09:27:12.33+01
10104043514061 2014-05-01 09:03:12.324+01
[root@zjj101 soft]#
新建一个普通的表并装载数据
sql:
-- 创建普通表
create table order_partition
(
order_no string,
order_time string
)
row format delimited fields terminated by '\t';
-- 装载数据
load data local inpath '/root/soft/order_created.txt' into table order_partition;
-- 查询数据是否装载成功
select *
from order_partition;
开始创建分区表
创建单一字段分区表
sql
create table order_dynamic_partition
(
order_no string
)
PARTITIONED BY (time string)
row format delimited fields terminated by '\t';
查询刚刚建的表 sql:
select *
from order_dynamic_partition;
建立动态分区并且装载数据
注意:使用,insert…select 往表中导入数据时,查询的字段个数必须和目标的字段个数相同,不能多,也不能少,否则会报错。但是如果字段的类型不一致的话,则会使用null值填充,不会报错。而使用load data形式往hive表中装载数据时,则不会检查。如果字段多了则会丢弃,少了则会null值填充。同样如果字段类型不一致,也是使用null值填充。
因为分区表只有一个字段 ,我们查询的时候系统默认用最后一个字段为分区名字,为分区表的
分区字段默认也是该表中的字段,且依次排在表中字段的最后面。所以分区需要分区的字段只能放在后面,不能把顺序弄错。如果我们查询了四个字段的话,则会报
错,因为该表加上分区字段也才三个。要注意系统是根据查询字段的位置推断分区名的,而不是字段名称
sql
-- 开启动态分区,默认是false
set hive.exec.dynamic.partition=true;
-- 开启允许所有分区都是动态的,否则必须要有静态分区才能使用。
set hive.exec.dynamic.partition.mode=nostrick;
-- 动态的插入分区表
insert overwrite table order_dynamic_partition
partition (time)
查询分区信息
show partitions order_dynamic_partition;
查询插入好的数据
select order_no, order_time
from order_partition;
半自动分区
多个分区字段时,实现半自动分区(部分字段静态分区,注意静态分区字段要在动态前面)
原始表的数据
select *
from order_partition;
创建两个分区字段的分区表
create table order_a
(
order_no string
) partitioned by (type string , time string );
以半动态分区插入数据
set hive.exec.dynamici.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table order_a
partition (type = 'china', time) -- type分区为静态,ct为动态分区,以查询的order_time字段为分区名
select order_no, order_time
from order_partition;
查询分区属性
show partitions order_a;
查询数据
select *
from order_a;
接着往分区表插入值
insert overwrite table order_a
partition (type = 'USA', time) -- type分区为静态,ct为动态分区,以查询的order_time字段为分区名
select order_no, order_time
from order_partition;
查询分区属性
sql
show partitions order_a;
查询结果
sql
select *
from order_a ;
sql
select *
from order_a where type = 'USA' ;
多字段全部实现动态分区插入
原始数据表
select *
from order_a;
创建分区表
sql:
create table order_b
(
order_no string
) partitioned by (type string , time string );
多字段全部动态插入数据
sql
— 注意:字段的个数和顺序不能弄错。
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nostrick;
insert overwrite table order_b
partition (type, time)
select order_no, type, `time`
from order_a;
查询导入结果
sql
select *
from order_b;
动态分区表的属性
使用动态分区表必须配置的参数 :
set hive.exec.dynamic.partition =true(默认false),表示开启动态分区功能
set hive.exec.dynamic.partition.mode = nonstrict(默认strict),表示允许所有分区都是动态的,否则必须有静态分区字段
动态分区相关的调优参数:
set hive.exec.max.dynamic.partitions.pernode=100 (默认100,一般可以设置大一点,比如1000) 表示每个maper或reducer可以允许创建的最大动态分区个数,默认是100,超出则会报错。
set hive.exec.max.dynamic.partitions =1000(默认值) 表示一个动态分区语句可以创建的最大动态分区个数,超出报错
set hive.exec.max.created.files =10000(默认) 全局可以创建的最大文件个数,超出报错。