Hive没有MapJoin对抗两个大表的联盟的小表

时间:2013-05-03 19:45:23

标签: hive hiveql

我有3个小表:smallTable0smallTable1smallTable3。它们都有少于100行和相同的模式。我还有3个大表:largeTable0largeTable1largeTable3。所有行都有超过1M行,具有相同的模式,与小表共享id列,在id之外的其他内容上进行分区(如果分区很重要,我怀疑它没有)。

设置hive.auto.convert.join=true后,以下情况会产生MapJoin,如预期的那样:

  • 加入smallTable0加入smallTable1
  • 加入smallTable0加入largeTable0
  • 加入smallTable0 <{1}}

以下情况不会像预期的那样导致MapJoin:

  • 加入smallTable1 UNION ALL smallTable2反对任何事情。
  • 使用largeTable0
  • 加入smallTable0

然而,出乎意料的是,以下情况也不会导致MapJoin:

  • 加入hive.auto.convert.join=false加入smallTable0

确切的查询如下:

largeTable0 UNION ALL largeTable1

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

Union运算符的源代码(here)有一条评论,我觉得有点神秘。

largetTable0 UNION ALL largeTable1

似乎暗示UNION运算符不允许使用显式MapJoin提示,但允许使用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; } 会启动MapJoins。但是我不明白为什么允许另一个人被禁止。除非“正常工作”意味着查询将“正常”,而不是使用MapJoin。但是,如果是这种情况,我原本希望将hive.auto.convert.join加入smallTable0以产生公共加入。

奇怪的行为是Hive中的错误,我的代码中的错误,Hive中缺少的功能,还是我的误解?

1 个答案:

答案 0 :(得分:1)

您可以为Hive指定提示,以便在连接期间处理表。我总是指定 MAPJOIN STREAMTABLE ,如果我知道小表是否适合加入,或者是非常大的表应该流式传输到其他表。

e.g。

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