前言
在《Hive 建表语句解析》文章中,建表的时候我们可以使用 PARTITIONED BY 子句和 CLUSTERED BY 子句来创建分区表和分桶表,为什么要创建分区表和分桶表呢?分区表和分桶表有什么区别呢?
分区表
1. 为什么分区
在Hive 查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此为了避免Hive全表扫描,建表时引入了partition概念,来提高查询效率。
注意:
- 在逻辑上分区表与非分区表没差别,在物理存储上,分区表会将数据按照指定的分区列值存储在不同的子目录中。
- 分区是以字段的形式在表结构中存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。
2. 分区类型
分区分为动态分区和静态分区两种类型
- 静态分区:
条件:需要明确指定分区列的值
应用场景:非常适合每日增量数据抽取和计算的任务场景。 - 动态分区
条件:设置如下参数
-- 1.打开动态分区模式: set hive.exec.dynamic.partition=true; -- 2.设置分区模式为非严格模式 set hive.exec.dynamic.partition.mode=nonstrict;
应用场景:不确定分区数量以及值的场景,比如初始化表的历史数据等。
分桶表
1. 分桶的作用
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
- 获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以大大较少JOIN的数据量。
- 使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
总结
Hive 中分区和分桶的目的都是为了提高查询分析效率,在物理上划分数据范围,两者的区别是分桶可以在分区的基础上进行更细粒度的数据划分。