Hive之分桶表解析
分区针对的是数据的存储路径;分桶针对的是数据文件。
分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区。
分桶是将数据集分解成更容易管理的若*分的另一个技术。
1、创建分桶表
create table stu_buck(
id int,
name string
)
clustered by(id) into 4 buckets
row format delimited fields terminated by '\t';
装载数据:
insert into table stu_buck
select id,name from stu;
注意:
需要设置以下两个属性值
set hive.enforce.bucketing=true;
set mapreduce.job.reduces=-1;
可见数据被分成4份
分区表和分桶表的区别:
(1)从表现形式上:
分区表是一个目录,分桶表是文件
(2)从创建语句上:
分区表使用partitioned by 子句指定,以指定字段为伪列,需要指定字段类型
分桶表由clustered by 子句指定,指定字段为真实字段,需要指定桶的个数
(3)从数量上:
分区表的分区个数可以增长,分桶表一旦指定,不能再增长
(4)从作用上:
分区避免全表扫描,根据分区列查询指定目录提高查询速度
分桶保存分桶查询结果的分桶结构(数据已经按照分桶字段进行了hash散列)。
分桶表数据进行抽样和JOIN时可以提高MR程序效率
2、分桶抽样查询
对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive 可以通过对表进行抽样来满足这个需求。
select * from stu_buck tablesample(bucket 1 out of 4 on id);
tablesample 是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。
y 必须是 table 总 bucket 数的倍数或者因子。hive 根据 y 的大小,决定抽样的比例。例如,table 总共分了 4 份,当 y=2 时,抽取(4/2=)2 个 bucket 的数据,当 y=8 时,抽取(4/8=)1/2个 bucket 的数据。
x 表示从哪个 bucket 开始抽取,如果需要取多个分区,以后的分区号为当前分区号加上y
例如,table 总 bucket 数为 4,tablesample(bucket 1 out of 2),表示总共抽取(4/2=)2 个bucket 的数据,抽取第 1(x)个和第 3(x+y)个 bucket 的数据。
注意:x 的值必须小于等于 y 的值,否则报错:FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck