hive中的动态分区和静态分区

本文详细介绍了Hive中动态分区的概念及其与静态分区的区别。动态分区允许根据查询结果自动创建分区,提高了数据处理效率。文章还讨论了动态分区在实际应用中的注意事项,包括合理设置reduce数量以避免namenode负载过高的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HIVE分区,实际上是通过一个路径来标识的,而不是在物理数据中。比如每天的数据,可能分区是pt=20121023这样,那么路径中它就会变成:/hdfs/path/pt=20121023/data_files。通过路径来标识的好处是,如果我们需要取特定分区的数据,只需要把这个路径下的数据取出来就可以了,不用扫描全部的数据。

HIVE默认是静态分区。但是有时候可能需要动态创建不同的分区,比如商品信息,我想根据它是否在线分成两个分区,这样后续如果要取在线商品,就只需要从在线的分区获取即可。动态分区可以通过下面的设置来打开:

set hive.exec.dynamic.partition=true;  

set hive.exec.dynamic.partition.mode=nonstrict;

然后代码里就可以这么写:

insert overwrite table tbl_name partition(pt, if_online)  

select field1, field2, ..., pt, if_online  

from tbl  

where xxx;

注意输入字段的最后面必须是动态分区字段。

看一下与静态分区写法的区别:

insert overwrite table tbl_name partition(pt=20121023, if_online=1)  

select field1, field2, ..., fieldn  

from tbl 

 where xxx;

动态分区与静态分区还有一个细微的差别是,静态分区一 定会创建分区,不管SELECT语句的结果有没有数据。而动态分区,只有在SELECT结果的记录数>0的时候,才会创建分区。因此在不同的业务场景下,可能会选择不同的方案。

另外使用动态分区时需要注意的比较重要的一点是,动态分区会为每一个分区分配reduce数。比如说你在脚本上面写了:set mapred.reduce.tasks=100;

并且有两个分区:pt, if_online。如果结果集中pt=20121023,if_online=0/1,那么它就会为pt=20121023/if_online=0,pt=20121023/if_online=1各分配100个reduce。也就是说,namenode会同时处理200个文件的写操作。这在分区值很多的情况下,会成为一个灾难,容易直接把namenode给搞挂掉,是非常危险的。因此使用动态分区时,一定要清楚地知道产生的动态分区值,并且合理地设置reduce数量.




### Hive 动态分区静态分区的区别 #### 定义 Hive支持两种类型的分区:静态分区(Static Partitioning, SP)动态分区(Dynamic Partitioning, DP)。静态分区分区值是在加载数据时显式指定的,而动态分区分区值是从输入数据中提取出来的[^1]。 #### 特点对比 - **配置需求** 对于静态分区而言,不需要特别启用任何功能即可使用;然而对于动态分区,则需开启特定的功能并适当调整参数设置以适应实际应用场景的需求[^2]。 - **灵活性** 动态分区提供了更高的灵活性,因为分区列可以从源表中的字段自动生成。相比之下,静态分区则要求用户手动为每一批次的数据指明所属的具体分区位置。 - **性能考量** 如果不加以控制的话,在某些情况下采用动态方式可能会造成过多的小文件被创建出来进而拖慢整体读取效率。因此建议合理规划好目标目录结构以及设定合适的阈值来防止这种情况发生。 #### 使用场景 ##### 静态分区适用情况 当处理流程相对固定,并且每次导入的新记录都属于已知范围内的有限几个类别之一时可以选择静态方法。比如按日期划分的日志归档操作就非常适合用这种方式来进行管理。 ##### 动态分区适合场合 如果业务逻辑较为复杂或者存在不确定性因素使得难以提前预估到所有可能出现的不同分类组合形式,那么此时应该优先考虑应用动态机制以便更好地应对变化多端的实际状况。例如电商网站的商品销售统计分析往往就需要依赖于此特性才能高效完成任务。 #### 示例代码展示 以下是两个简单的例子分别展示了如何实现这两种不同模式下的数据写入过程: ##### 插入数据至静态分区 ```sql INSERT INTO TABLE sales PARTITION (year='2023', month='04') SELECT * FROM raw_sales_data WHERE sale_date >= '2023-04-01' AND sale_date < '2023-05-01'; ``` ##### 启用并插入数据至动态分区 首先确保启用了必要的选项: ```sql SET hive.exec.dynamic.partition=true; SET hive.exec.dynamic.partition.mode=nonstrict; -- 允许任意级别的动态分区 ``` 接着可以执行如下语句向具有多个层次级联关系的目标表内添加新条目: ```sql INSERT INTO TABLE sales PARTITION (year, month) SELECT year(sale_date), month(sale_date), other_columns... FROM raw_sales_data; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值