hive groupby distinctの違いと性能比較

2752 ワード

Hiveデリ集計
Hiveを使用している人は、普段から統計を取りに行くとかよく使われていると思いますが、この重み取りの性能の問題にはあまり注目していないようですが、1つのテーブルのデータ量が非常に大きいと、簡単なcount(distinct order_no)という文が走るのが特に遅く、count(order_no)を直接運転する時間とはずいぶん違いますので、検討してみました.結論:group byの代わりにdistincを使用できるなら、distinctを使用しないでください.例:
実際の論証.
order_snapは注文のスナップショット表の総記録数763191489で、間もなく8億件近くの記録があります.総サイズ:108.877 GB、会社のすべての注文情報が格納されています.表のフィールドは20個ぐらいあります.その中で、注文番号は重複していません.だから、全部でどれだけの注文番号があるかを統計するときに、重さを保つかどうかの結果は同じです.すべての注文の数を統計して、count関数でできるsqlの性能はどうですか.
  • DISTINCT

  • 1
    2
    3
    4
    5
    6
    7
    select count(distinct order_no) from order_snap;
    Stage-Stage-1: Map:
    396 Reduce:
    1 Cumulative CPU: 7915.67 sec HDFS Read:
    119072894175 HDFS Write:
    10 SUCCESS
    Total MapReduce CPU Time Spent:
    0 days
    2 hours
    11 minutes
    55 seconds
    670 msec
    OK
    _c0
    763191489
    Time taken: 1818.864 seconds, Fetched:
    1 row(s)
  • GROUP BY

  • 1
    2
    3
    4
    5
    6
    7
    8
    select count(t.order_no) from (select order_no from order_snap group by order_no) t;
    Stage-Stage-1: Map:
    396 Reduce:
    457 Cumulative CPU: 10056.7 sec HDFS Read:
    119074266583 HDFS Write:
    53469 SUCCESS
    Stage-Stage-2: Map:
    177 Reduce:
    1 Cumulative CPU: 280.22 sec HDFS Read:
    472596 HDFS Write:
    10 SUCCESS
    Total MapReduce CPU Time Spent:
    0 days
    2 hours
    52 minutes
    16 seconds
    920 msec
    OK
    _c0
    763191489
    Time taken: 244.192 seconds, Fetched:
    1 row(s)
    結論:2つ目の書き方の性能は1つ目の7.448499541倍で、なぜこの違いがあるのかに気づきました.Hadoopは実は大きなデータを処理しています.Hiveはデータがどれだけ大きいかを恐れません.恐れているのはデータの傾きです.両者の出力情報を見てみましょう.
    1
    2
    3
    4
    # distinct
    Stage-Stage-1: Map:
    396 Reduce:
    1 Cumulative CPU: 7915.67 sec HDFS Read:
    119072894175 HDFS Write:
    10 SUCCESS
    # group by
    Stage-Stage-1: Map:
    396 Reduce:
    457 Cumulative CPU: 10056.7 sec HDFS Read:
    119074266583 HDFS Write:
    53469 SUCCESS
    猫が飽きたかどうかを発見したら、distinctを使ってすべてのorderをNoすべてshuffleは1つのreducerの中に入って、これは私たちが言ったデータの傾斜で、すべて1つのreducerに傾いてこのような性能は低くありませんか?2つ目は、直接注文番号を押してグループ化し、457個のreducerを起こし、複数のマシンにデータを分散して実行するので、時間はもちろん速いです.Reduceの個数を手動で指定していないため、Hiveはデータのサイズに応じて動的にReduceサイズを指定し、手動で指定することもできます.
    1
    hive> set mapred
    .reduce
    .tasks=
    100;
    このように、データ量が特に大きい場合は、distinctはなるべく使わないようにしましょう.しかし、1つの文の中で総記録本数と重さを除いた記録本数を見たい場合は、フィルタリングできないので、2つのsql文を使ってそれぞれ走ったり、union allを使ったり、普通のdistinctを使ったりする選択があります.具体的には状況を見て、直接distinctを使うのは可読性がよくて、データ量が大きくなければ使うことをお勧めして、もしデータが大きすぎて、性能が影響を受けたら、更に最適化を考慮します