Hive为什么要分桶?
1.获得更高的查询处理效率
在
分区数量过于庞大
以至于可能导致文件系统崩溃时,或数据集
找不到合理的分区字段
时,我们就 需要
使用分桶
来解决问题了。
分区中的数据可以被进一步拆分成桶
,不同于分区对列直接进行拆分,桶往往使用列的哈希值对数 据打散,并分发到各个不同的桶中从而完成数据的分桶过程。
注意,hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做
取余运算
的方式来桶, 保证了每个桶中都有数据,但每个桶中的数据条数
不一定相等
。
如果另外一个表也按照同样的规则分成了一个个小文件。
两个表join的时候
,就不必要扫描整个表,
只需要匹配相同分桶的数据即可,从而
提升效率。
在数据量足够大的情况下,分桶比分区有更高的查询效率。
(
2.数据采样
在真实的大数据分析过程中,由于数据量较大,
开发和自测的过程比较慢
,严重影响系统的开发进 度。此时就可以使用分桶来进行数据采样。采样使用的是一个
具有代表性的查询结果
而不是全部结果, 通过对采样数据的分析,来达到
快速开发和自测
的目的,节省大量的研发成本。
3.分桶和分区的区别
1. 分桶和分区两者不干扰,
可以把分区表进一步分桶
;
2. 分桶对数据的处理比分区
更加细粒度化
:分区针对的是数据的存储路径;
分桶针对的是数据 文件
;
3. 分桶是按照列的哈希函数进行分割的,相对
比较平均
;而分区是按照列的值来进行分割的, 容易造成
数据倾斜
。
4. 文本数据处理
注意
:对于分桶表,
不能使用load data的方式进行数据插入操作
,因为load data导入的数据不会 有分桶结构。
如何避免针对桶表使用load data插入数据的误操作呢?
--限制对桶表进行load操作
set hive.strict.checks.bucketing = true;
也可以在CM的hive配置项中修改此配置,当针对桶表执行load data操作时会报错。
那么对于文本数据如何处理呢?
(1. 先创建
临时表
,通过load data将txt文本导入临时表。
--创建临时表
create table temp_buck(id int, name string)
row format delimited fields terminated by '\t';
--导入数据
load data local inpath '/tools/test_buck.txt' into table temp_buck;
(2. 使用
insert select
语句间接的把数据从临时表导入到分桶表。
--启用桶表
set hive.enforce.bucketing=true;
--限制对桶表进行load操作
set hive.strict.checks.bucketing = true;
--insert select
insert into table test_buck select id, name from temp_buck;
--分桶成功