2016-12-20 8 views
1

I以下の(非常に単純な)ハイブのクエリを持っている:最適化ハイブGROUP BY

select user_id, event_id, min(time) as start, max(time) as end, 
     count(*) as total, count(interaction == 1) as clicks 
from events_all 
group by user_id, event_id; 

表以下の構造を有する:

user_id     event_id    time   interaction 
Ex833Lli36nxTvGTA1Dv juCUv6EnkVundBHSBzQevw 1430481530295 0 
Ex833Lli36nxTvGTA1Dv juCUv6EnkVundBHSBzQevw 1430481530295 1 
n0w4uQhOuXymj5jLaCMQ G+Oj6J9Q1nI1tuosq2ZM/g 1430512179696 0 
n0w4uQhOuXymj5jLaCMQ G+Oj6J9Q1nI1tuosq2ZM/g 1430512217124 0 
n0w4uQhOuXymj5jLaCMQ mqf38Xd6CAQtuvuKc5NlWQ 1430512179696 1 

私が知っているという事実のためにその行最初にuser_id、次にevent_idでソートされます。

質問は:行がソートされているので、クエリを最適化するためにHiveエンジンに "ヒント"する方法がありますか?最適化の目的は、グループを一度に1つずつ保持する必要があるため、すべてのグループをメモリに保持しないようにすることです。

現在、約300 GBのデータを持つ6ノードの16 GB Hadoopクラスタで実行されているこのクエリは、約30分かかり、ほとんどのRAMを使用してシステムを窒息させます。私は各グループが小さいので、(user_id, event_id)タプルごとに100行を超えることはないことを知っています。したがって、最適化された実行はおそらく非常に小さなメモリフットプリントを持ち、高速になります(グループキーをループする必要がないため)。

+0

'count(interaction == 1)'は私が期待したように動作していないので、1を持つ行だけをカウントし、代わりに 'count(*)'と同じものを返します。 –

+1

COUNTを含む集計関数はNULL値を無視し、FALSEはNULLではありません。 –

答えて

1

バケットソートテーブルを作成します。オプティマイザは、メタデータからソートされていることを認識します。 ここで例を参照してください(公式ドキュメント):https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-BucketedSortedTables

カウントのみの対話= 1:count(case when interaction=1 then 1 end) as clicks - 場合は、1またはnullですべての行をマークし、唯一の1秒をカウントします。

+0

ありがとう@leftjoin。いくつかのこと:最初に、私のテーブルは外部テーブルです、それを動作させる方法はありますか?第2に、外部表であるため、形式は固定されています(タブ区切り値、\ n終端行)。また、グループなどのターミネータも異なります。尋ねたくない場合は、私が投稿した特定の構造? –

+0

@Alejandro Piadこちらも読んでください:http://grokbase.com/t/hive/user/133xgs10cb/bucketing-external-tables – leftjoin

+0

私は残念ですが、バケツテーブルを作成して上書きする必要があるようです既存のテキストファイルの上に外部テーブルを作成すると機能しません。データを移動するには多くの時間がかかります。 – leftjoin