Hive針對distinct的優化 二

2021-08-14 08:58:08 字數 2073 閱讀 8819

之前一篇針對單個count(distinct ***)的優化,本文來講講對多個count(distinct ***)的優化。

優化是在之前單個count的基礎上,通過使用union all以及視窗分析函式lag的結合來進行的。具體思路如下。

select 

pid, c1, c2

from

(select

pid, c1, lag(c2,1) over win c2, row_number() over win rn

from

(select--取得c1的值

pid, sum(tn) c1, null c2

from

(select

pid, substr(uid,1,4) tag, count(distinct substr(uid, 5)) tn

from

xxtable

group

by

pid,substr(uid,1,4)

)t1group

by pid

union

allselect--取得c2的值

pid, null c1, sum(tn1) c2

from

(select

pid, substr(cid,1,4) tag, count(distinct substr(cid, 5)) tn1

from

xxtable

group

by

pid,substr(cid,1,4)

)t2group

by pid

)t3window win as (partition by pid order

by c1)

)t4where

rn = 2 --值取決於具體情況

經過驗證,該方法在5000萬資料量的情況下,不優化需要4.5分鐘,經過優化需要1.5分鐘,提公升效果較為明顯。

select 

pid, c1, c2

from

(select

pid, c1, lag(c2,1) over win c2, row_number() over win rn

from

(select

pid,sum(tc) c1 , null c2

from

(select

pid, count(1) tc,tag

from

(select

pid, cast(rand() * 100

as bigint) tag, uid

from

xxtable

group

by pid, uid

)t1

group

by pid, tag

)t2group

by pid

union

allselect

pid, null c1 , sum(tc) c2

from

(select

pid, count(1) tc,tag

from

(select

pid, cast(rand() * 100

as bigint) tag, class_id

from

xxtable

group

by pid, cid

)t1

group

by pid, tag

)t2group

by pid

)t3window win as (partition by pid order

by c1)

)t4where

rn = 2 --值取決於具體情況

經過驗證,該方法在5000萬資料量的情況下,不優化需要4.5分鐘,經過優化需要40秒,效果更加明顯。

針對distinct疑問引發的一系列思考

假設有如下這樣一張 這裡的資料,具有如下的特徵 在乙個departmentid中,可能會有多個name,反之也是一樣。就是說name和departmentid是多對多的關係。現在想實現這樣乙個查詢 按照departmentid排完序之後 第一步 再獲取name列的不重複值 第二步 而且要保留在第一步...

Hive之distinct多字段中出現null問題

在使用hive以多個字段作為唯一性依據進行統計時,如果某個字段出現大量null值,會發生統計結果不準確問題,解決辦法可以使用coalesce函式對空值進行替換。導致統計值異常的原因主要是因為 1.所有的null值會被歸併到一項 2.count結果並不會統計null項 假設原來是以及a,b兩個欄位去重...

匿名物件的Distinct

在使用linq distinct集合的時候,匿名物件和非匿名物件的區別非常有趣。匿名物件自動實現了gethashcode和equals方法,distinct可以自動去重。如果使用非匿名物件,則需要該類override gethashcode 和equals object obj 方法,或者新增乙個實...