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

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

289605

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

静态+动态分区

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

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

总结

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

分类:标签:
请先登录,感受更多精彩内容
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

世界最优秀的分布式文件系统架构演进之路
前言 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。Hadoop实现了一个分布式文件系
构建企业级业务高可用的延时消息中台
业务场景剖析公司业务系统(比如:电商系统)中有大量涉及定时任务的业务场景,例如:实现买卖双方在线沟通的IM系统,为了确保接收方能够收到消息,服务端一般都会有重试策略,即服务端在消息发出的一段时间内,如
5G时代,如何彻底搞定海量数据库的设计与实践
5G时代,业务数据越来越丰富,业务使用MySQL数据库作为后台存储,存储引擎使用InnoDB,会带来哪些挑战?如何针对公司业务特点及MySQL数据库特性,制定若干数据库使用规范供一线RD在设计业务时参
Redis client链接池配置不当引起的频繁full gc
现象笔者负责的一个RPC服务就是简单的从Redis Cluster中读取数据,然后返回给上游。理论上该服务的对象大部分都应该是朝生夕死的,但是笔者查看gc log 的时候发现 age =2 的对象还真
记一次线上请求偶尔变慢的排查
前言最近解决了个比较棘手的问题,由于排查过程挺有意思,于是就以此为素材写出了本篇文章。 Bug现场这是一个偶发的性能问题。在每天几百万比交易请求中,平均耗时大约为300ms,但总有那么100多笔会超过
MySQL之KEY分区引发的血案
需求背景业务表tb_image部分数据如下所示,其中id唯一,image_no不唯一。image_no表示每个文件的编号,每个文件在业务系统中会生成若干个文件,每个文件的唯一ID就是字段id:业务表t
记一次中间件导致的慢SQL排查过程
前言最近发现线上出现一个奇葩的问题,这问题让笔者定位了好长时间,期间排查问题的过程还是挺有意思的,正好博客也好久不更新了,就以此为素材写出了本篇文章。 Bug现场我们的分库分表中间件在经过一年的沉淀之
【全网首发】Hive分区暗藏各种玄机
大家好,我是球球,今天给大家分享一下Hive的静态分区与动态分区有什么不同,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获。也希望大家的点赞和转发。Hive是Hadoop的一个数据仓库工具,它的学习成本低,可以通过类SQL语句快速实现简单的MAPRed
5
0