【问题标题】:Hive on TEZ query taking forever at Reducer cross productTEZ 查询上的 Hive 在 Reducer 交叉产品中永远存在
【发布时间】:2020-08-26 00:13:42
【问题描述】:

我有 2 张桌子:

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

查找表只有一个名为 id 的列,它也存在并且是 main_table 的主键。目标是只查看查找表中的值并从 main_table 中删除所有存在这些值的行。 我正在使用这个 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 个容器)上永远挂起。

我收到了有关 Reducer 2 的警告

信息:警告:随机加入 MERGEJOIN[34][tables = [$hdt$_0, 阶段“Reducer 2”中的 $hdt$_1]] 是一个叉积

我正在为这个查询获得以下计划,该计划在 TEZ 的 Reducer 2 顶点处挂起。

我们能否请您提出一种方法,让这个 Reducer 2 可以获取更多容器或解决这个运行时间很长的工作的方法。解决方案将不胜感激。

【问题讨论】:

    标签: hadoop hive query-optimization hiveql apache-tez


    【解决方案1】:
    1. 如果查找表可以包含许多带有 NULL 的记录,这意味着至少 'RV' 记录在您的查询中不是唯一的,最好使用 DISTINCT 来减少连接前查找的大小。但是你说的是“..id,它也存在并且是 main_table 的主键......”主键是唯一的并且不是 NULL。如果 PK 约束确实由加载查找表的进程强制执行,则不需要 DISTINCT 和 NVL。主表也是如此。 PK = 唯一+NOT NULL。

    2. 如果主表有很多 NULL 并且在加入之前它们都将转换为 'NV',则此值可能会在 JOIN reducer 上产生偏差。如果应该传递“NV”,则可以完全将其从联接中排除。

    3. 这是最重要的一个。如果查找表足够小以适合内存,请使用 Map-Join。阅读这个关于 mapjoin 的问题:Hive Map-Join configuration mystery 而且它相当小:(2.5 KB) - Map-join 应该可以正常工作。

    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
    ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-11
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      • 2013-01-22
      • 2013-04-19
      • 2013-11-05
      相关资源
      最近更新 更多