Hive中支持两种模式的分区:
•静态分区SP(static partition)
•动态分区DP(dynamic partition)
静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说,静态分区的列实在编译时期,通过用户传递来决定的;动态分区只有在SQL执行时才能决定。不难看出,Hive分区主要是以缩小数据查询范围,提高查询速度和性能的。
动态分区在默认情况下是禁用的(在hive2.3.4版本中默认是开启的,可以在hive-default.xml.template文件中进行配置),所以需要将hive.exec.dynamic.partition设为true。默认情况下,用户必须至少指定一个静态分区列,这是为了避免意外覆盖分区。要禁用此限制,可以设置分区模式为非严格模式(即将hive.exec.dynamic.partition.mode设为nonstrict,默认值为strict)。可以选择在命令行终端方式设置:
代码语言:javascript复制SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;
或者你可以在hive-site.xml中这样设置:
-- Hive默认配置值-- 开启或关闭动态分区hive.exec.dynamic.partition=false;-- 设置为nonstrict模式,让所有分区都动态配置,否则至少需要指定一个分区值hive.exec.dynamic.partition.mode=strict;-- 能被mapper或reducer创建的最大动态分区数,超出而报错hive.exec.max.dynamic.partitions.pernode=100;-- 一条带有动态分区SQL语句所能创建的最大动态分区总数,超过则报错hive.exec.max.dynamic.partitions=1000;-- 全局能被创建文件数目的最大值,通过Hadoop计数器跟踪,若超过则报错hive.exec.max.created.files=100000; -- 根据个人需要配置set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;set hive.exec.max.dynamic.partitions.pernode=1000;set hive.exec.max.dynamic.partitions=10000;set hive.exec.max.created.files=1000000;
实战演示
首先我们创建一个表,并导入相关数据,作为源数据。
代码语言:javascript复制CREATE TABLE student_data(id STRING, name STRING, year INT, major INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
静态分区
创建一个表,用静态分区方式将数据导入此表。
代码语言:javascript复制CREATE TABLE student_static_partition(id STRING, name STRING)
PARTITIONED BY (year INT, major INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
使用静态分区方式,将源表中的所有数据导入此表:
代码语言:javascript复制INSERT INTO TABLE student_static_partition PARTITION(year=2001,major=810)
SELECT id,name FROM student_data WHERE year=2001 AND major=810;
INSERT INTO TABLE student_static_partition PARTITION(year=2001,major=820)
SELECT id,name FROM student_data WHERE year=2001 AND major=820;
INSERT INTO TABLE student_static_partition PARTITION(year=2002,major=810)
SELECT id,name FROM student_data WHERE year=2002 AND major=810;
INSERT INTO TABLE student_static_partition PARTITION(year=2002,major=820)
SELECT id,name FROM student_data WHERE year=2002 AND major=820;
导完后,查询该表的分区信息:
代码语言:javascript复制SHOW PARTITIONS student_static_partition;
---------------------- --
| partition |
---------------------- --
| year=2001/major=810 |
| year=2001/major=820 |
| year=2002/major=810 |
| year=2002/major=820 |
---------------------- --
动态分区
再创建一个相同表结构的表,准备以动态分区的方式导入数据。
代码语言:javascript复制CREATE TABLE student_dynamic_partition(id STRING, name STRING)
PARTITIONED BY (year INT, major INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
使用动态分区前,需要先配置相同的Hive参数,其中最重要的两个参数是:
代码语言:javascript复制set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
然后以动态分区方式导入数据:
代码语言:javascript复制INSERT OVERWRITE TABLE student_dynamic_partition PARTITION (year, major)
SELECT id,name,year,major
FROM student_data;
注意:在SELECT子句的各个字段应刚好与INSERT中的字段以及最后的PARTITION中的字段完全一致,包括顺序。
这里,我们无需指定数据导入到哪一个分区。该语句会自动创建相应分区,并将数据导入相应的分区。
导入完成后,查看该表的分区信息:
代码语言:javascript复制SHOW PARTITIONS student_dynamic_partition
---------------------- --
| partition |
---------------------- --
| year=2001/major=810 |
| year=2001/major=820 |
| year=2002/major=810 |
| year=2002/major=820 |
---------------------- --
与动态分区相关的一些参数如下:
代码语言:javascript复制-- Hive默认配置值
-- 开启或关闭动态分区
hive.exec.dynamic.partition=false;
-- 设置为nonstrict模式,让所有分区都动态配置,否则至少需要指定一个分区值
hive.exec.dynamic.partition.mode=strict;
-- 能被mapper或reducer创建的最大动态分区数,超出而报错
hive.exec.max.dynamic.partitions.pernode=100;
-- 一条带有动态分区SQL语句所能创建的最大动态分区总数,超过则报错
hive.exec.max.dynamic.partitions=1000;
-- 全局能被创建文件数目的最大值,通过Hadoop计数器跟踪,若超过则报错
hive.exec.max.created.files=100000;
-- 根据个人需要配置
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode=1000;
set hive.exec.max.dynamic.partitions=10000;
set hive.exec.max.created.files=1000000;