通过 clustered by(字段名) into bucket_num buckets 分桶,意思是根据字段名分成bucket_num个桶
create table test_bucket ( id int comment 'ID', name string comment '名字' ) comment '测试分桶' clustered by(id) into 4 buckets ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';buckt_data.txt
1,name1 2,name2 3,name3 4,name4 5,name5 6,name6 7,name7 8,name8 9,name9直接load data不会有分桶的效果,这样和不分桶一样,在HDFS上只有一个文件。
load data local inpath '/opt/test/buckt_data.txt' into table test_bucket;需要借助中间表
create table text_bucket_test ( id int comment 'ID', name string comment '名字' ) comment '测试分桶中间表' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ;先将数据load到中间表
load data local inpath '/opt/test/buckt_data.txt' into table text_bucket_test;然后通过下面的语句,将中间表的数据插入到分桶表中,这样会产生四个文件。
insert into test_bucket select * from text_bucket_test;然后我们查看分桶表的数据目录,发现好像也只有一个文件,并没有按之前的4个文件,也就是4个桶这样来划分。
分桶也就是分区,分区数量等于文件数,所以上面方法并没有分桶。
所以需要开启强制分桶:
set hive.enforce.bucketing = true; 开启强制分桶重新导入数据:
insert into test_bucket select * from text_bucket_test;发现组织文件的有变化:
用sql看和用hadoop命令看每个文件,结果每个桶内都是按id升序排序的,也就是和最开始的截图是一样的
因为每个桶内的数据是排序的,这样每个桶进行连接时就变成了高效的归并排序
假设表A和表B进行join,join的字段为id 条件:
1、两个表为大表2、两个表都为分桶表3、A表的桶数是B表桶数的倍数或因子这样join查询时候,表A的每个桶就可以和表B对应的桶直接join,而不用全表join,提高查询效率 比如A表桶数为4,B表桶数为8,那么桶数对应关系为
表A表B0011223304152637y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。
x表示从哪个bucket开始抽取。例如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。