Hive的分桶表
【分桶概述】
Hive表分区的实质是分目录(将超大表的数据按指定标准细分到指定目录),且分区的字段不属于Hive表中存在的字段;分桶的实质是分文件(将超大文件的数据按指定标准细分到分桶文件),且分桶的字段必须在Hive表中存在。
-
- 可以提高多表join的效率(因为通过分桶已经将超大数据集提取出来了。假如原数据被分了4个桶,此时2表join的时候只需要读取符合条件的一个分桶,则理论上效率可提升4倍)
- 加速数据抽样的效率(理由同上,只需要按照指定规则抽取指定分桶的数据即可,不需要扫描全表)
select * from tableName tablesample(bucket x out of y on colum)。其中: x:表示从第x个桶中抽取数据 y:表示每y个桶中抽取一次数据(必须是分桶数量的倍数 or 因子)
【用法简介】
1.开启支持分桶
set hive.enforce.bucketing=true; -- 默认:false --
设置为 true 之后,mr 运行时会根据 bucket 的个数自动分配 reduce task的个数。
当然,用户也可以通过 mapred.reduce.tasks 自己设置 reduce 任务个数,但分桶时不推荐使用。注意:一次作业产生的桶(文件数量)和 reduce task 个数一致)
2.往分桶表中加载数据
/* 往分桶表中插入数据的语法类似下面 */ insert into table bucket_table select columns from tbl; -- 全新插入 -- insert overwrite table bucket_table select columns from tbl; -- 覆盖重写 --
3.分桶表数据抽样
/* 抽样语法:TABLESAMPLE(BUCKET x OUT OF y)。其中: x:表示从第x个桶中抽取数据 y:表示每y个桶中抽取一次数据(必须是分桶数量的倍数 or 因子) */ select * from bucket_table tablesample(bucket 1 out of 4 on columns);
【用法举例】
1. 假设本地文件 /root/hivedata/ft 中有以下内容:
zhang 12 lisi 34 wange 23 zhouyu 15 guoji 45 xiafen 48 yanggu 78 liuwu 41 zhuto 66 madan 71 sichua 89
2. 新建Hive常规表并导入本地文件:
hive> CREATE TABLE ft( id INT, name STRING, age INT) > ROW FORMAT DELIMITED FIELDS TERMINATED BY'\t'; OK Time taken: 0.216 seconds hive> load data local inpath'/root/hivedata/ft' into table ft; Loading data to table hehe.ft Table hehe.ft stats: [numFiles=1, totalSize=127] OK Time taken: 1.105 seconds hive> select *from ft; OK 1 zhang 12 2 lisi 34 3 wange 23 4 zhouyu 15 5 guoji 45 6 xiafen 48 7 yanggu 78 8 liuwu 41 9 zhuto 66 10 madan 71 11 sichua 89 NULL NULL NULL Time taken: 0.229 seconds, Fetched: 12 row(s)
3. 创建分桶表:
hive> create table fentong( > id int, > name string, > age int,)clustered by(age) into 4 buckets -- 以字段age来划分成4个桶 -- > row format delimited fields terminated by ',';
每行数据具体落入几号分桶的规则如下:
-
- 用表中指定的字段值(比如age)来除以桶的个数4;
- 结果取余数,也就是求模(若余数为0就放到1号桶,余数为1就放到2号桶,余数为2就放到3号桶,余数为3就放到4号桶)
4. 给分桶表导入数据:
hive> insert into table fentong select name,age from ft;
5. 查询分桶表数据以确认正确导入:
hive> select * from fentong
6. 我们来看看分桶表的数据如何使用:
hive> select id, name, age from fentong tablesample(bucket 1 out of 4 on age); OK NULL NULL NULL 6 xiafen 48 1 zhang 12 hive> select id, name, age from fentong tablesample(bucket 2 out of 4 on age); OK 11 sichua 89 8 liuwu 41 5 guoji 45 hive> select id, name, age from fentong tablesample(bucket 3 out of 4 on age); OK 9 zhuto 66 7 yanggu 78 2 lisi 34