hive group by distinct區別以及性能比較


Hive去重統計

相信使用Hive的人平時會經常用到去重統計之類的吧,但是好像平時很少關注這個去重的性能問題,但是當一個表的數據量非常大的時候,會發現一個簡單的count(distinct order_no)這種語句跑的特別慢,和直接運行count(order_no)的時間差了很多,於是研究了一下。
先說結論:能使用group by代替distinc就不要使用distinct,例子:

實際論證

order_snap為訂單的快照表 總記錄條數763191489,即將近8億條記錄,總大小:108.877GB,存儲的是公司所有的訂單信息,表的字段大概有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)

結論:第二種寫法的性能是第一種的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到一個reducer里面,這就是我們所說的數據傾斜,都傾斜到一個reducer這樣性能能不低么?再看第二個,直接按訂單號分組,起了457個reducer,將數據分布到多台機器上執行,時間當然快了.
由於沒有手動指定Reduce的個數,Hive會根據數據的大小動態的指定Reduce大小,你也可以手動指定

 
             
1
 
             
hive> set mapred .reduce.tasks=100;

 

類似這樣,所以如果數據量特別大的情況下,盡量不要使用distinct吧。
但是如果你想在一條語句里看總記錄條數以及去重之后的記錄條數,那沒有辦法過濾,所以你有兩個選擇,要么使用兩個sql語句分別跑,然后union all或者就使用普通的distinct。具體來說得看具體情況,直接使用distinct可讀性好,數據量如果不大的話推薦使用,如果數據太大了,性能受到影響了,再考慮優化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM