对于每一个表或者分区,Hive可以进一步组织成桶。Hive也是针对某一列进行桶的组织。
Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。比如将表test按照ID分成5个桶,其算法是hash(id) % 5(桶的个数),这样,hash(id) % 5 = 0的数据被放到第一个桶中,hash(id) % 5 = 1的记录被放到第二个桶中。
物理上,每个桶就是表(或分区)目录里的一个文件。
创建桶表
在DDL创建表的教程中,已经说明如何创建桶表,回顾一下:
先设置两个变量,再通过clustered by创建。
hive (default)> set hive.enforce.bucketing = true;
hive (default)> set mapred.reduce.tasks = 3;
hive (default)> create table bucket_table(id int,age int,name string)
> clustered by(id) sorted by(age) into 5 buckets
> row format delimited fields terminated by ',';
桶表插入数据
插入数据的时候不适合load 因为不走mapreduce程序 而桶表的底层原理是MapReduce。
因此比较适合从别的表插入的情况insert into buk_table select XX,XX from XXX;
hive (default)> insert into table bucket_table select id,age,name from origin;
Query ID = root_20180508112323_fcea5f4c-d7e3-4939-bcd1-8b002cdb44b5
Total jobs = 1
Launching Job 1 out of 1
2018-05-08 11:23:29,788 Stage-1 map = 0%, reduce = 0%
2018-05-08 11:23:37,113 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 2.06 sec
2018-05-08 11:23:45,436 Stage-1 map = 100%, reduce = 100%, Cumulative CPU 3.41 sec
MapReduce Total cumulative CPU time: 3 seconds 410 msec
既然创建的时候指定了into 5 buckets 即对应了5个桶(文件)
查看对应的文件,可以发现,相同id的落在了一个桶!(因为创建的时候clustered by(id)指定的是id,如果指定的是age那么相同age会在一个桶),至于为什么000000_0文件对应id=5呢?上面说了,hash(id) % 5 = 0的数据会被放到第一个桶中。
[root@master local]# hadoop fs -cat /user/hive/warehouse/bucket_table/000000_0
5,16,sssss
5,16,sss
5,16,ss
5,16,s
[root@master local]# hadoop fs -cat /user/hive/warehouse/bucket_table/000001_0
1,12,qqqqq
1,12,qqq
1,12,qq
1,12,q
既然相同id的落在了一个桶!那就不难得出桶表的作用之一:简化Join操作
既然把数据分散在不同的桶,那就不难得出桶表的作用之二:可用于抽样
桶表作用之一:简化Join
可以提升join的性能(join的字段是分桶字段),因为分桶可以确保某个key对应的数据在一个特定的桶内(文件),所以巧妙地选择分桶字段可以大幅度提升join的性能。通常情况下,分桶字段可以选择经常用在过滤操作或者join操作的字段
比如JOIN操作:
select a.name,b.cname from students a join courses b where a.id=b.cid;
原始join做法 既然是要找到a表b表中id相等的数据,那么进行全表扫描找到a和b中id相等的数据。
如果有桶表,HIVE可以在map阶段对分桶数据进行连接。比如,两个表有一个相同的列,对这两个表都进行了桶操作。那么同一个id落在了同一个桶,那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
桶表作用之二:抽样
使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y ON Column)
hive (default)> select * from bucket_table tablesample(bucket 5 out of 10 on id);
OK
bucket_table.id bucket_table.age bucket_table.name
4 15 wwwww
4 15 wwww
4 15 ww
4 15 w
y必须是桶数的整数倍或者因子。hive根据y的大小,决定抽样的比例。例如,桶数64:
当y=32时,抽取(64/32=)2个bucket的数据
当y=64时,抽取(64/64=)1个bucket的数据(此例子就是1)
当y=128时,抽取(64/128=)1/2个bucket的数据
x表示从哪个bucket开始抽取。例如,桶数64,tablesample(bucket3outof32),表示:
BDStar原创文章。发布者:Liuyanling,转载请注明出处:http://bigdata-star.com/archives/1072