Hive 配置单元不会将一个小表映射到两个大表的并集

Hive 配置单元不会将一个小表映射到两个大表的并集,hive,hiveql,Hive,Hiveql,我有3个小表:smallTable0,smallTable1,和smallTable3。它们都只有不到100行和相同的模式。我还有3个大表:largeTable0、largeTable1和largeTable3。所有这些表都有超过一百万行,具有相同的模式,与小表共享id列,在id之外的其他内容上进行分区(如果分区有问题,我怀疑它没有) 设置hive.auto.convert.join=true后,以下情况会产生预期的映射连接: 将smallTable0与smallTable1 加入smallT

我有3个小表:
smallTable0
smallTable1
,和
smallTable3
。它们都只有不到100行和相同的模式。我还有3个大表:
largeTable0
largeTable1
largeTable3
。所有这些表都有超过一百万行,具有相同的模式,与小表共享
id
列,在
id
之外的其他内容上进行分区(如果分区有问题,我怀疑它没有)

设置
hive.auto.convert.join=true
后,以下情况会产生预期的映射连接:

  • smallTable0
    smallTable1
  • 加入
    smallTable0
    largettable0
  • smallTable0
    smallTable1联合所有smallTable2
以下情况不会产生预期的映射联接:

  • 加入
    largeTable0
    对抗任何东西
  • 使用
    hive.auto.convert.join=false将
    smallTable0
    加入到任何对象中
但是,出乎意料的是,以下情况也不会导致MapJoin:

  • smallTable0
    largettable0联合所有largettable1
具体查询如下:

SELECT * FROM smallTable0 s
JOIN (
  SELECT * FROM (
    SELECT * FROM largeTable0
    UNION ALL
    SELECT * FROM largeTable1 
  ) x
) l
  ON s.id = l.id;
它运行正常,但是使用了一个公共连接而不是MapJoin,这会导致性能下降。创建表示
largeTable0 UNION ALL largeTable1
的视图无法解决此问题。我确信创建一个
largetTable0 UNION ALL largettable1
的表可以解决这个问题,但是复制这么多数据然后保持同步是不可取的

Union操作符()的源代码中有一条注释,我觉得有点神秘

/**
* Union operators are not allowed either before or after a explicit mapjoin hint.
* Note that, the same query would just work without the mapjoin hint (by setting
* hive.auto.convert.join to true).
**/
@Override
public boolean opAllowedBeforeMapJoin() {
  return false;
}

@Override
public boolean opAllowedAfterMapJoin() {
  return false;
}
这似乎表明UNION运算符不允许带有显式的MapJoin提示,但允许带有由
hive.auto.convert.join启动的MapJoin的UNION运算符。然而,我不明白为什么一个会被允许,另一个会被禁止。除非“justwork”意味着查询将“work”,否则不能使用MapJoin。但是,如果是这种情况,我希望将
smallTable0
加入到
smallTable1联合所有smallTable2
中,以产生一个公共联接


这种奇怪的行为是由于配置单元中的错误、我的代码中的错误、配置单元中缺少的功能或我的误解造成的吗?

您可以为配置单元指定在连接期间处理表的提示。我总是指定MAPJOINSTREAMTABLE,如果我知道一个小表是否是join的候选表,或者应该流式传输到其他表的非常大的表

e、 g

SELECT /*+ MAPJOIN(smalltable0) */ * FROM smallTable0 s