Hiveのバージョンと構成によっては、質問に対する回答が異なる場合があります。 正確なクエリを2つのテーブルのcreateステートメントおよびそれらのサイズの見積もりと共有することができれば、より簡単になります。
問題をよりよく理解するために、Hiveで「通常の」内部結合がどのように機能するかについて説明します。
ハイブは、MapReduceの中で参加する:ここで
は、MapReduceのにコンパイルされるインナーはハイブに参加する方法を簡単に説明します。一般的には、次のような結合問合せを持つ2つのテーブルT1およびT2を持っている場合:
、t1が以下の内容を持っている
SELECT
t1.key, t1.value, t2.value
FROM
t1
JOIN
t2 (ON t1.key = t2.key);
:
、t2は次のような内容がある
k_1 v1_1
k_2 v1_2
k_3 v1_3
:
を
k_2 v2_2
k_3 v2_3
k_4 v2_4
我々は
k_2 v1_2 v2_2
k_3 v1_3 v2_3
する結合結果を期待します
テーブルがHDFSに格納されていると仮定すると、その内容はファイル分割に分割されます。マッパーはファイル分割を入力としてテーブルのキー列としてキーを出力し、テーブルのvalue列とフラグ(レコードがどのテーブルかを表す、つまりt1またはt2)を合成した値を出力します。 。 T2の間
k_1, <v1_1, t1>
k_2, <v1_2, t1>
k_3, <v1_3, t1>
:
k_2, <v2_2, t2>
k_3, <v2_3, t2>
k_4, <v2_4, t2>
は今、これらのうち放出されるレコードが同じキーを持つすべてのレコードをまとめてグループ化に送られ、シャッフル相を経るT1の場合
減速機。各reduce操作のコンテキストは、1つのキーと、そのキーに対応するすべての値を含むリストです。実際には、1つの減速器がいくつかの減速操作を実行する。
上記の例では、我々は次のグループになるだろう。ここでは
k_1, <<v1_1, t1>>
k_2, <<v1_2, t1>, <v2_2, t2>>
k_3, <<v1_3, t1>, <v2_3, t2>>
k_4, <<v2_4, t2>>
は減速に何が起こるかです。値のリスト内の値のそれぞれについて、値が異なる表に対応する場合、減算器は乗算を実行します。
k_1では、t2からの値はなく、何も出力されません。
K_2ために、値の乗算が放出される - K_2、v1_2、V2_2(各テーブルからの1つの値があるので、1×1 = 1)
K_3については、値の乗算が放出される - K_3、v1_3 、v2_3(各テーブルから1つの値があるので、1x1 = 1)
k_4の場合、t1の値はなく、何も出力されません。 したがって、内部結合から期待した結果が得られます。
私はどうしますか?
データに歪みが存在する可能性があります。換言すれば、減速器がデータを取得すると、キーに対応する値のリストが非常に長くなり、エラーが生じる。 問題を緩和するには、JVMで使用可能なメモリを増やしてみてください。これを行うには、mapred.child.java.opts
をhive-site.xmlに-Xmx512M
のような値に設定します。 Hiveシェルでset mapred.child.java.opts;
を実行すると、このパラメーターの現在の値を照会できます。
"通常の"結合の代替方法を試すことができます。マップ結合。上記のジョインの説明は、レデューサーで結合が行われる通常のジョインに適用されます。あなたが使用しているHiveのバージョンによって、Hiveは通常の結合をマップ結合に自動的に変換することができます。これは(結合がマップフェーズで行われるため)高速です。最適化を有効にするには、hive.auto.convert.join
をtrue
に設定します。このプロパティは、true
にhive.auto.convert.join
の設定に加えて
Hive 0.7に導入された、あなたはまた、true
にhive.optimize.skewjoin
を設定することができます。これは、1に記載されているデータの問題のスキューを回避します。
本当に解決策ではなく正しい答えを感謝する独自の解決策を受け入れる代わりに、彼の解決策に同意するならば、Mark Groverの回答を「受け入れる」必要があります。上記のコメントに –
+1しかし、私は彼が新しいので、彼はここでどのように動作するか分からなかったかもしれないと思う。 –