性能文章>【全网首发】Hive分区暗藏各种玄机>

【全网首发】Hive分区暗藏各种玄机原创

427619

大家好,我是球球,今天给大家分享一下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语句。

静态+动态分区

  • 部分字段静态分区,部分动态分区
  • 多个分区字段时,会实现半自动分区

注意:静态分区字段要在动态的前面

总结

这是我总结一下我碰到的一些问题,如果你们碰到的还有其他问题可以私聊我,我一定会完善我的文档。如果有哪里不太正确的也欢迎大家的指点。欢迎大家的指正。

点赞收藏
分类:标签:
大数据球球

大数据技术布道者

请先登录,查看1条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步
9
1