【Hive-优化】Hive的优化方式二(分桶优化)
1)为什么使用分桶表
1.1.数据采样
在真实的开发环境中,表中的数据量比较大,如果用原有的表,我们开发和自测的过程会比较慢,严重影响系统的开发进度。
因此可以采用分桶表的方式进行采样,但是分桶表进行采样的结果并不是真正准确的结果,而是一个比较具有代表性的结果。
语法:
select * from table tablesample(bucket x out of y on column)
x:从哪个桶开始采样
Y:用表中抽样的比例,用建表时的总桶数÷y=抽取多少个桶的数据
x的值必须小于等于y的值,不然会报异常
例如:
table总bucket数为6
,tablesample(bucket 1 out of 2)
,表示总共抽取(6/2=)3
个bucket的数据,从第1
个bucket开始,抽取第1(x)
个和第3(x+y)
个和第5(x+y)
个bucket的数据。
注意:tablesample(bucket x out of y on column)
这个函数必须放在表名的后面
,如果给表起了别名
,别名也要放在这个函数后面
(紧跟table)
1.2.获得更高效的查询处理效率
当表中的数据比价庞大
的时候,主要是在对两个表
或者多个表
进行join
的时候,我们使用分桶表
可以提升我们的查询处理效率。
2)分桶表中join的三种优化方式
2.1.Map Join
主要进行大小表的关联
:
在实际情况中,有一个表很
,有一个表很小
,但是这两个表要进行join
,此时可以采用Map Join
的方式进行优化。
此时会把这个小表放在每一个map的内存中进行提前join
,就不会等到了reduce中再进行join了
。
在hive0.7之前,需要吧小表放在大表的前面join。
条件:
(1)开启map join:
set hive.auto.convert.join=true;
(2)设置何为小表的阈值(默认的大小为20M):
set hive.auto.convert.join.noconditionaltask.size=512000000
2.2.Bucket-MapJoin
两个表进行join的过程中,有一个表非常大
,但是另一个表不大不小
,此时我们使用Bucket-MapJoin
,这个方法就是,把两个表都使用bucket进行分桶
,并且小表的bucket数要设置成能被大表的bucket整除
。
条件:
(1)开启Bucket-MapJoin
set hive.optimize.bucketmapjoin = true;
(2)一个表的bucket数是另一个表bucket数的整数倍。
(3)bucket列 == join列(分桶的字段==join相关联的字段)
(4)必须是应用在map join的场景中。
(5)如果表不是bucket的话,默认使用普通的join。
2.3.SMB-Join
全称Sort Merge Bucket Joi
。
如果我们需要对两个大表进行join
,此时上面的两种join都满足不了我们的需求了,此时就用到了SMB-Join
(基于Bucket -Join
的基础上,做一个sorted by 的有序bucket
)这样可以有效地减少了shuffle的数据量
。
条件:
(1)必须应用在Bucket-MapJoin的基础上
(2)要在hive中多set几个我们需要开启的功能
(3)两个表的bucket数量要相等
(4)分桶的字段=join的关联查询字段=sort(排序)的字段
3)总结
(1)综上,涉及到分桶表操作的齐全配置为:
#写入数据强制分桶
set hive.enforce.bucketing=true;
#写入数据强制排序
set hive.enforce.sorting=true;
#开启bucketmapjoin
set hive.optimize.bucketmapjoin = true;
#开启SMB Join
set hive.auto.convert.sortmerge.join=true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
(2)下面的都已经默认开启
了,所以无需配置
:
1、开启MapJoin
的配置(hive.auto.convert.join
和hive.auto.convert.join.noconditionaltask.size
)还有限制对桶表进行load操作(hive.strict.checks.bucketing
)可以直接设置在hive的配置项中,无需在sql中声明。
2、自动尝试SMB
联接(hive.optimize.bucketmapjoin.sortedmerge
)也可以在设置中进行提前配置。