Hive—分桶及抽样查询
一、分桶
1.1介绍
分区针对的是数据的存储路径;分桶针对的是数据文件。
分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区,特别是之前所提到过的要确定合适的划分大小这个疑虑。
分桶是将数据集分解成更容易管理的若干部分的另一个技术。
2.原理
Hive中:按照分桶字段的hash值去模除以分桶的个数。
3.作用
1、方便抽样。
使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
2、提高join查询效率
获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
二、数据操作
1) 数据准备
1001 ss1 1002 ss2 1003 ss3 1004 ss4 1005 ss5 1006 ss6 1007 ss7 1008 ss8 1009 ss9 1010 ss10 1011 ss11 1012 ss12 1013 ss13 1014 ss14 1015 ss15 1016 ss16
2)创建分桶表及临时表
hive (default)> create table stu_buck(id int, name string) > clustered by(id) > into 4 buckets > row format delimited fields terminated by > '\t';
hive (default)> create table stu(id int, name string) > row format delimited fields terminated by > '\t';
3)上传数据至临时表
hive (default)> load data local inpath '/opt/module/datas/test.txt' into table stu; Loading data to table default.stu Table default.stu stats: [numFiles=1, totalSize=151] OK Time taken: 0.49 seconds
4)开启分桶功能
hive (default)> set hive.enforce.bucketing=true;
默认:false;设置为 true 之后,mr 运行时会根据 bucket 的个数自动分配 reduce task 个数。
5)导入数据至分桶表
hive (default)> insert into stu_buck select id,name from stu;
6)查询数据
hive (default)> select * from stu_buck; OK stu_buck.id stu_buck.name 1016 ss16 1012 ss12 1008 ss8 1004 ss4 1009 ss9 1005 ss5 1001 ss1 1013 ss13 1010 ss10 1002 ss2 1006 ss6 1014 ss14 1003 ss3 1011 ss11 1007 ss7 1015 ss15 Time taken: 0.05 seconds, Fetched: 16 row(s)
分桶:根据id的值出分桶bucket=4,按余数进行分桶。
三、抽样查询
1.分桶抽样查询
hive (default)> select * from stu_buck tablesample(bucket 1 out of 4 on id); OK stu_buck.id stu_buck.name 1016 ss16 1012 ss12 1008 ss8 1004 ss4 Time taken: 0.615 seconds, Fetched: 4 row(s)
注: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的值,否则
hive (default)> select * from stu_buck tablesample(bucket 3 out of 2 on id); FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck
整理源于atguigu视频