首先,Hive的group by和count(distinct)都是去除重複的數據,某種程度上來講,二者產生的結果是同樣的。大數據
實例代碼:code
select a,count(distinct b) from t group by a select tt.a,count(tt.b) from (select a,b from t group by a,b)tt group by tt.a
上面兩句代碼產生的結果是同樣的,可是二者從效率和空間複雜度上來說,是有很大的差異的。排序
distinct會將b列全部的數據保存到內存中,造成一個相似hash的結構,速度是十分的塊;可是在大數據背景下,由於b列全部的值都會造成以key值,極有可能發生OOM。內存
group by會先把b列的值進行排序,若是以快速派序來講的話,他的空間複雜度就是O(1),時間複雜度是O(nlogn),這樣在大數據的環境下,只有排序階段會比較慢,時間複雜度是O(nlogn)。hash
二者比較來講,distinct 耗費內存,可是效率極高,可是數據較大時,可能會產生OOM;group by若是在時間複雜度容許的狀況下,能夠展示出突出的空間複雜度的優點。效率
使用distinct會將全部的數據都shuffle到一個reducer裏面,group by會分組,將數據分佈到多臺機器上執行。select
最後,對於Hive來講,含有distinct的HQL語句,若是遇到瓶頸,想要調優,第一時間都是想到用group by來替換distinct來實現對數據的去重。數據