我有两张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可以得到更多的容器或一种方法来解决这个非常长的运行任务。我们将不胜感激。
1条答案
按热度按时间brjng4g31#
如果查找表可以包含许多带null的记录,这意味着至少“rv”记录在查询中不是唯一的,最好在联接之前使用distinct来减小查找的大小。但您所说的“..id,它也存在,并且是主表的主键…”主键是唯一的,不为空。如果pk约束是由进程加载查找表强制执行的,则不需要distinct和nvl。主桌也一样。pk=唯一+不为空。
如果主表有许多空值,并且它们在使用join之前都将转换为“nv”,那么这个值可以在join reducer上创建一个skew。如果应该传递'nv',则可以将其从联接中完全排除。
这是最重要的一个。如果查找表足够小,可以放入内存中,请使用map join。阅读这个关于mapjoin的问题:配置单元mapjoin配置很神秘,而且它相当小:(2.5 kb)-mapjoin肯定可以工作。