hive-on-tez查询在reducer交叉乘积中永远使用

oyxsuwqo  于 2021-05-31  发布在  Hadoop
关注(0)|答案(1)|浏览(434)

我有两张table:

db1.main_table (32 GB)
db2.lookup_table (2.5 KB)

查找表只有一个名为id的列,该列也存在,并且是主表的主键。目标是只查看查找表中的值,并从主表中删除所有存在这些值的行。我正在使用这个Hive查询(在tez上),它在reduce阶段突然开始创建一个交叉产品。

insert overwrite table 
db1.main_table 
select * from db1.main_table where nvl(id,'NV') not in (select nvl(id,'RV') from db2.lookup_table);

我使用nvl是因为在我的id列的主表中存在空值,我不想丢失它。
我的查询将永远挂在reducer 2(只有3个容器)上。
我收到减速机2的警告
信息:警告:阶段“reducer 2”中的shuffle join mergejoin[34][tables=[$hdt$\u 0,$hdt$\u 1]]是交叉乘积
我得到了这个查询的以下计划,它挂在了tez的reducer 2顶点。

我们能不能建议一种方法,这个减速机2可以得到更多的容器或一种方法来解决这个非常长的运行任务。我们将不胜感激。

brjng4g3

brjng4g31#

如果查找表可以包含许多带null的记录,这意味着至少“rv”记录在查询中不是唯一的,最好在联接之前使用distinct来减小查找的大小。但您所说的“..id,它也存在,并且是主表的主键…”主键是唯一的,不为空。如果pk约束是由进程加载查找表强制执行的,则不需要distinct和nvl。主桌也一样。pk=唯一+不为空。
如果主表有许多空值,并且它们在使用join之前都将转换为“nv”,那么这个值可以在join reducer上创建一个skew。如果应该传递'nv',则可以将其从联接中完全排除。
这是最重要的一个。如果查找表足够小,可以放入内存中,请使用map join。阅读这个关于mapjoin的问题:配置单元mapjoin配置很神秘,而且它相当小:(2.5 kb)-mapjoin肯定可以工作。

set hive.auto.convert.join=true; 
set hive.mapjoin.smalltable.filesize=157286400; --adjust the figure for mapjoin

insert overwrite table db1.main_table 
select m.* 
  from db1.main_table m 
       left join (select DISTINCT nvl(id,'RV') id from db2.lookup_table) l 
              on m.id=l.id --NULLs are not joined
 where l.id is NULL --Not joined records, including NULLs in main table
;

相关问题