2、hive的分区
2.1、为何要分区
检索数据的时候减少扫描成本、提升查询效率
hive的每个分区有很多的子目录,在存储数据的时候会将数据按照分区放到不同的子目录中
为了更好的体现出分区的效果,分区的条件最好能够对应where语句的部分查询条件,这样才能体现出分区的性能优势
2.2静态分区
根据插入时是否需要手动指定分区可以分为:*静态分区*:导入数据时需要手动指定分区。*动态分区*:导入数据时,系统可以动态判断目标分区。
2.2.1创建静态分区
##静态分区创建
CREATE [EXTERNAL] TABLE <table_name>
(<col_name> <data_type> [, <col_name> <data_type> ...])
-- 指定分区键和数据类型
PARTITIONED BY (<partition_key> <data_type>, ...)
[ROW FORMAT <row_format>]
[STORED AS TEXTFILE|ORC|CSVFILE]
[LOCATION '<file_path>']
[TBLPROPERTIES ('<property_name>'='<property_value>', ...)];
--分区字段主要是时间,按年分区
CREATE TABLE device_open (
deviceid varchar(50),
...
)
PARTITIONED BY (year varchar(50))
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
##插入数据
-- 覆盖写入
INSERT OVERWRITE TABLE <table_name>
PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...])
SELECT <select_statement>;
-- 追加写入
INSERT INTO TABLE <table_name>
PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...])
SELECT <select_statement>;
insert overwrite table device_open partition(year=’2020’)
select
...,
original_device_open.month as month,
original_device_open.day as day,
original_device_open.hour as hour
FROM original_device_open
2.3、动态分区
动态分区的创建和静态分区时一样的
##语法
--分区字段主要是时间,分为年,月,日,时
CREATE TABLE device_open (
deviceid varchar(50),
...
)
PARTITIONED BY (year varchar(50), month varchar(50), day varchar(50), hour varchar(50))
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
##插入数据
-- 开启动态分区支持,并开启非严格模式
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table device_open partition(year,month,day,hour)
select
...,
original_device_open.year as year,
original_device_open.month as month,
original_device_open.day as day,
original_device_open.hour as hour
FROM original_device_open
set hive.exec.dynamic.partition=true; 是开启动态分区
set hive.exec.dynamic.partition.mode=nonstrict; 这个属性默认值是strict,就是要求分区字段必须有一个是静态的分区值。全部动态分区插入,需要设置为nonstrict非严格模式。
2.4静态分区和动态分区的混合使用
一张表可同时被静态和动态分区键分区,只是****动态分区键需要放在静态分区**键**的后面(**因为HDFS上的动态分区目录下不能包含静态分区的子目录)**。****
#静态分区键要用 <spk>=<value> 指定分区值;动态分区只需要给出分区键名称 <dpk>。
spk 即静态分区static partition key, dpk 即动态分区dynamic partition key。
insert overwrite table device_open partition(year='2017',month='05',day,hour)
select
...,
original_device_open.day as day,
original_device_open.hour as hour
FROM original_device_open
where original_device_open.year='2017' and original_device_open.month='05'
partition(year='2017', month='05', day, hour),year和month是静态分区字段,day和hour是动态分区字段,这里指将2017年5月份的数据插入分区表,对应底层的物理操作就是将2017年5月份的数据load到hdfs上对应2017年5月份下的所有day和hour目录中去。
注意混用的情况下,静态分区的上层必须也是静态分区,如果partition(year, month, day=’05’, hour=’08’),则会报错:FAILED: SemanticException [Error 10094]: Line 1:50 Dynamic partition cannot be the parent of a static partition ''day''。