hive groupby distinctの違いと性能比較
2752 ワード
Hiveデリ集計
Hiveを使用している人は、普段から統計を取りに行くとかよく使われていると思いますが、この重み取りの性能の問題にはあまり注目していないようですが、1つのテーブルのデータ量が非常に大きいと、簡単な
実際の論証.
order_snapは注文のスナップショット表の総記録数763191489で、間もなく8億件近くの記録があります.総サイズ:108.877 GB、会社のすべての注文情報が格納されています.表のフィールドは20個ぐらいあります.その中で、注文番号は重複していません.だから、全部でどれだけの注文番号があるかを統計するときに、重さを保つかどうかの結果は同じです.すべての注文の数を統計して、 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つ目の
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個の
1
hive> set mapred
.reduce
.tasks=
100;
このように、データ量が特に大きい場合は、
Hiveを使用している人は、普段から統計を取りに行くとかよく使われていると思いますが、この重み取りの性能の問題にはあまり注目していないようですが、1つのテーブルのデータ量が非常に大きいと、簡単な
count(distinct order_no)
という文が走るのが特に遅く、count(order_no)
を直接運転する時間とはずいぶん違いますので、検討してみました.結論:group by
の代わりにdistinc
を使用できるなら、distinct
を使用しないでください.例:実際の論証.
order_snapは注文のスナップショット表の総記録数763191489で、間もなく8億件近くの記録があります.総サイズ:108.877 GB、会社のすべての注文情報が格納されています.表のフィールドは20個ぐらいあります.その中で、注文番号は重複していません.だから、全部でどれだけの注文番号があるかを統計するときに、重さを保つかどうかの結果は同じです.すべての注文の数を統計して、
count
関数でできるsqlの性能はどうですか.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)
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を使うのは可読性がよくて、データ量が大きくなければ使うことをお勧めして、もしデータが大きすぎて、性能が影響を受けたら、更に最適化を考慮します