1. 程式人生 > >hive distinct優化

hive distinct優化

hive針對count(distinct xxx)只產生一個reduce的優化。

0x00 造成的原因

由於使用了distinct,導致在map端的combine無法合併重複資料;對於這種count()全聚合操作時,即使設定了reduce task個數,set mapred.reduce.tasks=100;hive也只會啟動一個reducer。這就造成了所有map端傳來的資料都在一個tasks中執行,成為了效能瓶頸。

0x01 解決方式一(分治法)

該方法優勢在於使用不同的reducer各自進行COUNT(DISTINCT)計算,充分發揮hadoop的優勢,然後進行求和,間接達到了效果。需要注意的是多個tasks同時計算產生重複值的問題,所以分組需要使用到目標列的子串。

    SELECT 
        SUM(tmp_num) total
    FROM
        (select
            substr(uid,1,4) tag,
            count(distinct substr(uid,5)) tmp_total
        from
            xxtable
        group by
            substr(uid,1,4)
        )t1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

經過驗證,該方法在5000萬資料量的情況下,不優化需要5分鐘,經過優化需要3分鐘,還是有一定的提升的。

0x10 解決方式二(隨機分組法)

核心是使用group by替代count(distinct)。

SELECT--3
    SUM(tc) 
FROM
    (select--2 
        count(*) tc,
        tag  
    from 
        (select--1
            cast(rand() * 100 as bigint) tag,
            user_id 
        from 
            xxtable
        group by  
            user_id
        )t1 
    group by
tag )t2;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1層使用隨機數作為分組依據,同時使用group by保證去重
  • 2層統計各分組下的統計數。
  • 3層對分組結果求和。

經過驗證,該方法在5000萬資料量的情況下,不優化需要5分鐘,經過優化需要2.5分鐘,有進一步提升。