我在执行bucketed map join方面遇到了问题。
我正在使用配置单元 0.10 。
Table1 是年,月,日的分区表。每个分区数据由列c1分成128个桶。我每天有近1亿条记录。
Table 1
create table1
(
....
....
)
partitioned by (year int,month int,day int)
CLUSTERED BY(c1) INTO 128 BUCKETS;
Table2 是列c1上的大型查找表。我有8000万条记录加载到128个桶中。
Table 2
create table2
(
c1
c2
...
)
CLUSTERED BY(c1) INTO 128 BUCKETS;
我检查了数据,并将其按预期加载到存储桶中。
现在,我正在尝试强制执行bucketed map join。那就是我被困住的地方。
set hive.auto.convert.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.mapjoin.bucket.cache.size=1000000;
select a.c1 as c1_tb2,a.c2
b.c1,b....
from table2 a
JOIN table1 b
ON (a.c1=b.c1);
我仍然没有得到布局的地图加入。我错过了什么吗?甚至我试图只在1个分区上执行连接。但是,我仍然得到相同的结果。
或者
Bucketed map join不能分区表吗?
请帮忙。谢谢。
答案 0 :(得分:1)
此解释适用于Hive 0.13。 AFAICT,分段地图连接不会对自动转换的地图连接生效。您需要在语法中显式调出map join,如下所示:
set hive.optimize.bucketmapjoin = true;
explain extended select /* +MAPJOIN(b) */ count(*)
from nation_b1 a
join nation_b2 b on (a.n_regionkey = b.n_regionkey);
请注意,只有说明扩展显示了指示是否正在使用桶映射连接的标志。在计划中寻找这一行。
BucketMapJoin: true
答案 1 :(得分:0)
表格在蜂巢中被分开,以单独管理/处理部分数据。它将使该过程易于管理并在性能方面高效。 让我们了解数据存储在存储桶中时的连接:
假设有两个表user和user_visits,并且两个表数据都是使用4个桶中的user_id进行的。这意味着用户的存储桶1将包含与user_visits的存储桶1具有相同用户ID的行。如果在user_id列上对这两个表执行连接,如果可以将两个表的存储桶1发送到同一个映射器,则可以实现大量优化。这完全是在bucketed map join中完成的。
存储桶映射连接的先决条件:
正在连接的表在连接列上被bucketized, 一个表中的桶数与另一个表中的桶数相同/倍。 存储桶可以相互连接,如果连接的表在连接列上进行了bucketized。如果表A有4个桶,而表B有4个桶,则以下连接
SELECT /*+ MAPJOIN(b) */ a.key, a.valueFROM a JOIN b ON a.key = b.key
只能在mapper上完成。不是为A的每个映射器完全取出B,而是仅获取所需的桶。对于上面的查询,A的映射器处理桶1将仅获取B的桶1.它不是默认行为,并且由以下参数控制
set hive.optimize.bucketmapjoin = true
如果正在连接的表在连接列上进行排序和缓冲,并且它们具有相同数量的存储区,则可以执行排序合并连接。相应的桶在映射器处相互连接。如果A和B都有4个桶,
SELECT /*+ MAPJOIN(b) */ a.key, a.valueFROM A a JOIN B b ON a.key = b.key
只能在mapper上完成。 A的存储区映射器将遍历B的相应存储区。这不是默认行为,需要设置以下参数:
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;