0

smallTable0smallTable1、およびの3 つの小さなテーブルがありsmallTable3ます。それらはすべて 100 行未満で、同一のスキーマを持っています。largeTable0largeTable1、およびの3 つの大きなテーブルもありlargeTable3ます。すべてが1Mを超える行を持ち、同一のスキーマを持ち、id列を小さなテーブルと共有し、それ以外のものでパーティション化されていますid(パーティション化が問題になる場合、そうではないと思います)。

を設定した後hive.auto.convert.join=true、次の場合は予想どおり MapJoin になります。

  • 参加smallTable0するsmallTable1
  • 参加smallTable0するlargeTable0
  • に参加smallTable0するsmallTable1 UNION ALL smallTable2

次の場合は、予想どおり MapJoin になりません。

  • largeTable0何に対しても参加。
  • smallTable0何に対しても参加するhive.auto.convert.join=false

ただし、予想外に、次のケースでも MapJoin は発生しません。

  • 参加smallTable0するlargeTable0 UNION ALL largeTable1

正確なクエリは次のとおりです。

SELECT * FROM smallTable0 s
JOIN (
  SELECT * FROM (
    SELECT * FROM largeTable0
    UNION ALL
    SELECT * FROM largeTable1 
  ) x
) l
  ON s.id = l.id;

正常に動作しますが、MapJoin ではなく Common Join を使用しているため、パフォーマンス ヒットが発生しています。を表すビューを作成してlargeTable0 UNION ALL largeTable1も、問題は解決しません。問題を解決するテーブルを作成すると確信していますがlargetTable0 UNION ALL largeTable1、大量のデータを複製して同期を維持することは望ましくありません。

Union 演算子のソース コード ( here ) には、やや不可解なコメントがあります。

/**
* 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 ヒントでは許可されていませんが、 UNION 演算子は の結果として開始された MapJoins では許可されているようですhive.auto.convert.join。ただし、一方が許可され、もう一方が許可されない理由がわかりません。MapJoin ではなく、クエリが「機能する」ことを意味する場合を除きます。ただし、これが事実である場合、結合smallTable0するsmallTable1 UNION ALL smallTable2と Common Join になると予想していました。

奇妙な動作は、Hive のバグ、コードのバグ、Hive の機能の欠落、または私の側の誤解の結果ですか?

4

1 に答える 1

1

結合中にテーブルを処理するためのヒントを Hive に指定できます。小さなテーブルが結合の候補であるか、または他のテーブルにストリーミングする必要がある非常に大きなテーブルであるかがわかっている場合は、常にMAPJOINまたはSTREAMTABLEを指定します。

例えば

SELECT /*+ MAPJOIN(smalltable0) */ * FROM smallTable0 s
于 2013-05-07T14:08:34.537 に答える