有序數組查找是O(logn),但是去重的話需要先查找刪除位再把刪除位后的數據前移,這一步復雜度是O(n),因此有序數組去重的總復雜度是O(n)
無序數組去重,以C++的duplicate函數為例,先對無序數組排序,時間復雜度是O(nlogn),然后有序數組去重,則總復雜度是O(nlogn)
摘自https://www.cnblogs.com/dancesir/p/7505730.html,為distinct和group by去重的比較
distinct需要將col列中的全部內容都存儲在一個內存中,可以理解為一個hash結構,key為col的值,最后計算hash結構中有多少個key即可得到結果。時間復雜度為O(1)
很明顯,需要將所有不同的值都存起來。內存消耗可能較大。
而group by的方式是先將col排序。而數據庫中的group一般使用sort的方法,即數據庫會先對col進行排序。而排序的基本理論是,時間復雜為nlogn,空間為1.,然后只要單純的計數就可以了。優點是空間復雜度小,缺點是要進行一次排序,執行時間會較長。
兩中方法各有優劣,在使用的時候,我們需要根據實際情況進行取舍。
具體情況可參考如下法則
數據分布 | 去重方式 | 原因 |
離散 | group | distinct空間占用較大,在時間復雜度允許的情況下,group 可以發揮空間復雜度優勢 |
集中 | distinct | distinct空間占用較小,可以發揮時間復雜度優勢 |
兩個極端:
1.數據列的所有數據都一樣,即去重計數的結果為1時,用distinct最佳
2.如果數據列唯一,沒有相同數值,用group 最好
使用distinct會將所有的數據都shuffle到一個reducer里面,group by會分組,將數據分布到多台機器上執行。
最后,對於Hive來說,含有distinct的HQL語句,如果遇到瓶頸,想要調優,第一時間都是想到用group by來替換distinct來實現對數據的去重。