hive中groupby和distinct區別以及性能比較


Hive去重統計

先說核心:

都會在map階段count,但reduce階段,distinct只有一個, group by 可以有多個進行並行聚合,所以group by會快。

 

經常在公司還能看到。很多老人用distinct去重,很容易數據量大的時候的數據傾斜。感謝上次沖哥的指正。

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

實際論證

order_snap為訂單的快照表 總記錄條數763191489,即將近8億條記錄,總大小:108.877GB,存儲的是公司所有的訂單信息,表的字段大概有20個,其中訂單號是沒有重復的,所以在統計總共有多少訂單號的時候去重不去重結果都一樣,我們來看看:
統計所有的訂單有多少條條數,一個count函數就可以搞定的sql性能如何。

  • DISTINCT
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
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並不怕數據有多大,怕的就是數據傾斜,我們看看兩者的輸出信息:

# 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大小,但是可以手動指定

hive> set mapred.reduce.tasks=100

 


免責聲明!

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



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