smallTable0
、smallTable1
、およびの3 つの小さなテーブルがありsmallTable3
ます。それらはすべて 100 行未満で、同一のスキーマを持っています。largeTable0
、largeTable1
、およびの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 の機能の欠落、または私の側の誤解の結果ですか?