【全网首发】Hive分区暗藏各种玄机原创
大家好,我是球球,今天给大家分享一下Hive的静态分区与动态分区有什么不同,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获。也希望大家的点赞和转发。
Hive是Hadoop的一个数据仓库工具,它的学习成本低,可以通过类SQL语句快速实现简单的MAPReduce统计,十分适合数据仓库的统计。在Hive学习过程中必定会接触到分区,这是Hive存放数据的一种形式。查询数据时使用分区列进行过滤,只需根据列值直接扫描对应目录下的数据,不扫描其他不关心的分区,快速定位,提高查询效率。分区分为静态分区和动态分区两种形式。
静态分区SP(static partition)
若分区的值是确定的,那么称为静态分区。静态分区是手动指定,新增分区或者是加载分区数据时,已经指定分区名。静态分区的列是在编译时期,通过用户传递来决定的。
- 建表语句
CREATE TABLE tmp.org_test(
org_code string default null comment '机构编码',
inst_tm date DEFAULT NULL COMMENT '插入日期'
)
COMMENT ''
PARTITIONED BY (
data_date varchar2(8))
CLUSTERED BY (
org_code)
INTO 7 BUCKETS
stored as orc
TBLPROPERTIES ('transactional'='true');
;
- 插入数据到指定分区
第一种
INSERT INTO tmp.org_test partition(data_date = '2021-02-01')(
org_code ,
inst_tm
)
SELECT
org_code ,
inst_tm
FROM tmp.org_test_20220711;
第二种
INSERT INTO tmp.org_test (
org_code ,
inst_tm ,
data_date
)
SELECT
org_code ,
inst_tm ,
'2021-02-01'
FROM tmp.org_test_20220711;
这两种在低版本的hive中执行都没什么问题,但是高版本默认的规则是第一种,所以大家尽量多用一种方式插入语句。(我问了好几位大佬,如果要是他的下属用第二种的一定会被打回去重新写的)。这也是现在数仓的默认规范。
小结
1.默认:静态分区。
2.设置静态分区:
设置:set hiveexec.dynamic.partition=false;查看设置:sethive.exec.dynamic.partition;
3.分区的列: 伪列,是不存在的字段。
4.不方便之处,在于: 使用动态插入的时候不方便。
5.具体怎么不方便: 一个表有分区,另一个表也有分区,那么,不可以直接插入数据。
6.为什么不能:因为,我们查询出来的分区值是一个字段,而另一个表中没有这个字段,所以插入不进去
- 新增分区指定分区名
alter table tmp.org_test add partition(data_date='2021-02-02') partition(data_date='2021-02-01');
- 删除分区
-- 删除分区
alter table tmp.org_test drop partition (data_date='2021-02-01');
动态分区DP(dynamic partition)
分区的值是非确定的,由输入数据来确定。动态分区是通过数据来进行判断。动态分区的值只有在SQL执行时才能决定。
1、动态分区的相关属性:
hive.exec.dynamic.partition=true :是否允许动态分区
hive.exec.dynamic.partition.mode=strict :分区模式设置
strict:最少需要有一个是静态分区
nostrict:可以全部是动态分区
hive.exec.max.dynamic.partitions=1000 :允许动态分区的最大数量
hive.exec.max.dynamic.partitions.pernode =100 :单个节点上的mapper/reducer允许创建的最大分区
2、动态分区的操作
- 创建分区表
CREATE TABLE tmp.org_test(
org_code string default null comment '机构编码',
inst_tm date DEFAULT NULL COMMENT '插入日期'
)
COMMENT ''
PARTITIONED BY (
data_date varchar2(8))
CLUSTERED BY (
org_code)
INTO 7 BUCKETS
stored as orc
TBLPROPERTIES ('transactional'='true');
;
- 插入分区表
INSERT INTO tmp.org_test partition(data_date )(
org_code ,
inst_tm
)
SELECT
org_code ,
inst_tm ,
data_date
FROM tmp.org_test_20220711;
严格和非严格模式
create table if not exists tmp.usertest
(uid int,
commentid bigint,
recommentid bigint)
partitioned by(year int,month int,day int)
row format delimited fields terminated by '\t';
- 严格模式
insert into table tmp.usertest partition(year=2022,month,day)
select uid,commentid,recommentid,month,day from tmp;
- 非严格模式
##设置非严格模式动态分区
set hive.exec.dynamic.partition.mode=nostrict;
##创建动态分区表
create table if not exists tmp.usertest2
(uid int,
commentid bigint,
recommentid bigint)
partitioned by(year int,month int,day int)
row format delimited fields terminated by '\t';
##为非严格模式动态分区加载数据
insert into table tmp.usertest2 partition(year,month,day)
select uid,commentid,recommentid,year,month,day from tmp;
- 删除分区
-- 删除分区
-- 第一种
alter table tmp.org_test drop partition (data_date='2021-02-01');
-- 第二种(orc格式 开启分桶 开启事务可以使用)
DELETE FROM tmp.org_test PARTITION(data_date='2021-02-01)
分区注意细节
1、尽量不要用动态分区,因为动态分区的时候,将会为每一个分区分配reducer数量,当分区数量多的时候,reducer数量将会增加,对服务器是一种灾难。
2、动态分区和静态分区的区别,静态分区不管有没有数据都将会创建该分区,动态分区是有结果集将创建,否则不创建。
3、hive动态分区的严格模式和hive提供的hive.mapred.mode的严格模式。hive提供我们一个严格模式:为了阻止用户不小心提交恶意hql hive.mapred.mode=nostrict : strict 如果该模式值为strict,将会阻止以下三种查询:
(1)、对分区表查询,where中过滤字段不是分区字段。
(2)、笛卡尔积join查询,join查询语句,不带on条件或者where条件。
(3)、对order by查询,有order by的查询不带limit语句。
静态+动态分区
- 部分字段静态分区,部分动态分区
- 多个分区字段时,会实现半自动分区
注意:静态分区字段要在动态的前面
总结
这是我总结一下我碰到的一些问题,如果你们碰到的还有其他问题可以私聊我,我一定会完善我的文档。如果有哪里不太正确的也欢迎大家的指点。欢迎大家的指正。