Hive-查询(四)分桶及抽样查询 - MissRong

时间:2024-03-04 13:52:15

Hive查询(四)分桶及抽样查询

一、分桶表数据存储

分区针对的是数据的存储路径;分桶针对的是数据文件。

分区提供一个隔离数据和优化查询的便利方式。不过,并非所有的数据集都可形成合理的分区,特别是之前所提到过的要确定合适的划分大小这个疑虑。

分桶是将数据集分解成更容易管理的若*分的另一个技术。

1.先创建分桶表,通过直接导入数据文件的方式

1)数据准备

 2)创建分桶表

create table stu_buck1(id int, name string)

clustered by(id)

into 4 buckets

row format delimited fields terminated by \'\t\';

3)查看表结构

hive (default)> desc formatted stu_buck;

Num Buckets:            4     

4)导入数据到分桶表中

hive (default)> load data local inpath \'/opt/module/hiveTest/s/student.txt\' into table stu_buck1;

5)查看创建的分桶表中是否分成4个桶

 

 

 

 发现并没有分成4个桶。是什么原因呢?(load加载方式不会分桶)

2.创建分桶表时,数据通过子查询的方式导入

1)先建一个普通的stu表

create table stu(id int, name string)

row format delimited fields terminated by \'\t\';

2)向普通的stu表中导入数据

load data local inpath \'/opt/module/hiveTest/s/student.txt\' into table stu;

3)清空stu_buck表中数据

truncate table stu_buck1;

select * from stu_buck1;

4)导入数据到分桶表,通过子查询的方式

insert into table stu_buck1

select id, name from stu;

5)发现还是只有一个分桶

 

 

 

 6)需要设置一个属性

hive (default)> set hive.enforce.bucketing;

hive.enforce.bucketing=false

将分桶属性设置为true

hive (default)> set hive.enforce.bucketing=true;

hive (default)> set mapreduce.job.reduces=-1;

hive (default)> truncate table stu_buck1;

hive (default)> insert into table stu_buck1

select id, name from stu;

  

 

 

 7)查询分桶的数据

hive (default)> select * from stu_buck1;

OK

stu_buck1.id stu_buck1.name

1040 黄忠

1036 董卓

1032 妲己

1028 墨菲特

1024 干将

1020 孙斌

1016 嬴政

1012 刘备

1008 诸葛亮

1004 赵六

1005 李琪

1029 易

1037 马谡

1017 韩信

1001 张三

1033 吕布

1009 司马懿

1013 曹操

1025 白起

1021 大桥

1010 张飞

1038 夏侯?

1022 小乔

1034 张苞

1002 李四

1026 李白

1018 孙权

1030 亚瑟

1014 曹植

1006 赵云

1015 曹丕

1007 黄月英

1027 李信

1023 鲁班

1019 孙尚香

1003 王五

1011     关羽

1039 夏侯渊

1035 鲁肃

1031 安其拉

二、分桶抽样查询

对于非常大的数据集,有时用户需要使用的是一个具有代表性的查询结果而不是全部结果。Hive可以通过对表进行抽样来满足这个需求。

查询表stu_buck1中的数据。

hive (default)> select * from stu_buck1 tablesample(bucket 1 out of 4 on id);

OK

stu_buck1.id stu_buck1.name

1040 黄忠

1036 董卓

1032 妲己

1028 墨菲特

1024 干将

1020 孙斌

1016 嬴政

1012 刘备

1008 诸葛亮

1004 赵六

Time taken: 2.768 seconds, Fetched: 10 row(s)

注:tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y) 。

hive (default)> select * from stu_buck1 tablesample(bucket 1 out of 3 on id);

不是桶数的倍数或者因子也可以,但是不推荐。

y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例

例如,table总共分了4份(4个bucket),当y=2时,抽取(4/2=)2个bucket的数据,当y=8时,抽取(4/8=)1/2个bucket的数据。

hive (default)> select * from stu_buck tablesample(bucket 1 out of 2 on id);

x表示从哪个bucket开始抽取。

例如,table总bucket数为4,tablesample(bucket 4 out of 4),表示总共抽取(4/4=)1个bucket的数据,抽取第4个bucket的数据。

hive (default)> select * from stu_buck tablesample(bucket 1 out of 8 on id);

OK

stu_buck1.id stu_buck1.name

1040 黄忠

1032 妲己

1024 干将

1016 嬴政

1008 诸葛亮

Time taken: 0.388 seconds, Fetched: 5 row(s)

注意:x的值必须小于等于y的值,否则

FAILED: SemanticException [Error 10061]: Numerator should not be bigger than denominator in sample clause for table stu_buck

三、数据块抽样

Hive提供了另外一种按照百分比进行抽样的方式,这种是基于行数的,按照输入路径下的数据块百分比进行的抽样。

hive (default)> select * from stu tablesample(0.1 percent) ;

提示:这种抽样方式不一定适用于所有的文件格式。另外,这种抽样的最小抽样单元是一个HDFS数据块。因此,如果表的数据大小小于普通的块大小128M的话,那么将会返回所有行。