關於distinct 和group by的去重邏輯淺析

【轉】http://liuzhiqiangruc.iteye.com/blog/1461038

在數據庫操作中,我們常常遇到需要將數據去重計數的工作。例如:

表A,列col

A

C

A

B

C

D

A

B

 

結果就是一共出現4個不同的字母A、B、C、D

即結果爲4

大體上我們可以選擇count(distinct col)的方法和group+count的方法。

分別爲:

select count(distinct col) from A;

select count(1) from (select 1 from A group by col) alias;

 

兩中方法實現有什麼不同呢?

 

其實上述兩中方法分別是在運算和存儲上的權衡。

distinct需要將col列中的全部內容都存儲在一個內存中,可以理解爲一個hash結構,key爲col的值,最後計算hash結構中有多少個key即可得到結果。

很明顯,需要將所有不同的值都存起來。內存消耗可能較大。

 

而group by的方式是先將col排序。而數據庫中的group一般使用sort的方法,即數據庫會先對col進行排序。而排序的基本理論是,時間複雜爲nlogn,空間爲1.,然後只要單純的計數就可以了。優點是空間複雜度小,缺點是要進行一次排序,執行時間會較長。

 

 

兩中方法各有優劣,在使用的時候,我們需要根據實際情況進行取捨。

具體情況可參考如下法則

 

數據分佈 去重方式 原因
離散 group distinct空間佔用較大,在時間複雜度允許的情況下,group 可以發揮空間複雜度優勢
集中 distinct distinct空間佔用較小,可以發揮時間複雜度優勢

 

兩個極端:

1.數據列的所有數據都一樣,即去重計數的結果爲1時,用distinct最佳

2.如果數據列唯一,沒有相同數值,用group 最好

 

 

當然,在group by時,某些數據庫產品會根據數據列的情況智能地選擇是使用排序去重還是hash去重,例如postgresql。當然,我們可以根據實際情況對執行計劃進行人工的干預,而這不是這裏要討論的話題了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章