Hive之COUNT DISTINCT優(yōu)化

COUNT(DISTINCT xxx) 在hive中很容易造成數(shù)據(jù)傾斜。針對這一情況窄赋,網(wǎng)上已有很多優(yōu)化方法哟冬,這里不再贅述。

但有時忆绰,“數(shù)據(jù)傾斜”又幾乎是必然的柒傻。我們來舉個例子:

假設(shè)表detail_sdk_session中記錄了訪問某網(wǎng)站M的客戶端會話信息,即:如果用戶A打開app客戶端较木,則會產(chǎn)生一條會話信息記錄在該表中红符,該表的粒度為“一次”會話,其中每次會話都記錄了用戶的唯一標示uuid,uuid是一個很長的字符串预侯,假定其長度為64位≈驴現(xiàn)在的需求是:每天統(tǒng)計當月的活用用戶數(shù)——“月活躍用戶數(shù)”(當月訪問過app就為活躍用戶)。我們以2016年1月為例進行說明萎馅,now表示當前日期双戳。

最簡單的方法

這個問題邏輯上很簡單,SQL也很容易寫出來糜芳,例如:

SELECT
  COUNT(DISTINCT uuid)
FROM detail_sdk_session t
WHERE t.date >= '2016-01-01' AND t.date <= now

上述SQL代碼中飒货,now表示當天的日期。很容易想到峭竣,越接近月末塘辅,上面的統(tǒng)計的數(shù)據(jù)量就會越大。更重要的是皆撩,在這種情況下扣墩,“數(shù)據(jù)傾斜”是必然的,因為只有一個reducer在進行COUNT(DISTINCT uuid)的計算扛吞,所有的數(shù)據(jù)都流向唯一的一個reducer呻惕,不傾斜才怪。

優(yōu)化1

其實滥比,在COUNT(DISTINCT xxx)的時候亚脆,我們可以采用“分治”的思想來解決。對于上面的例子盲泛,首先我們按照uuid的前n位進行GROUP BY濒持,并做COUNT(DISTINCT )操作,然后再對所有的COUNT(DISTINCT)結(jié)果進行求和查乒。

我們先把SQL寫出來弥喉,然后再做分析。

-- 外層SELECT求和
SELECT
  SUM(mau_part) mau
FROM
(
  -- 內(nèi)層SELECT分別進行COUNT(DISTINCT)計算
  SELECT
    substr(uuid, 1, 3) uuid_part,
    COUNT(DISTINCT substr(uuid, 4)) AS mau_part
  FROM detail_sdk_session
  WHERE partition_date >= '2016-01-01' AND partition_date <= now
  GROUP BY substr(uuid, 1, 3)
) t;

上述SQL中玛迄,內(nèi)層SELECT根據(jù)uuid的前3位進行GROUP BY由境,并計算相應(yīng)的活躍用戶數(shù)COUNT(DISTINCT),外層SELECT求和蓖议,得到最終的月活躍用戶數(shù)虏杰。

這種方法的好處在于,在不同的reducer各自進行COUNT(DISTINCT)計算勒虾,充分發(fā)揮hadoop的優(yōu)勢纺阔,然后進行求和。

注意修然,上面SQL中笛钝,n設(shè)為3质况,不應(yīng)過大。

為什么n不應(yīng)該太大呢玻靡?

我們假定uuid是由字母和數(shù)字組成的:大寫字母结榄、小寫字母和數(shù)字,字符總數(shù)為26+26+10=62囤捻。

理論上臼朗,內(nèi)層SELECT進行GROUP BY時,會有 62^n 個分組蝎土,外層SELECT就會進行 62^n 次求和视哑。所以n不宜過大。

當然誊涯,如果數(shù)據(jù)量十分巨大挡毅,n必須充分大,才能保證內(nèi)層SELECT中的COUNT(DISTINCT)能夠計算出來醋拧,此時可以再嵌套一層SELECT慷嗜,這里不再贅述淀弹。

優(yōu)化2

其實丹壕,很多博客中都記錄了使用GROUP BY 操作代替 COUNT(DISTINCT) 操作抵赢,但有時僅僅使用GROUP BY操作還不夠焕窝,還需要加點小技巧。

還是先來看一下代碼:

--  第三層SELECT
SELECT
  SUM(s.mau_part) mau
FROM
(
  -- 第二層SELECT
  SELECT
    tag,
    COUNT(*) mau_part
  FROM
  (
    -- 第一層SELECT
    SELECT
      uuid, 
      CAST(RAND() * 100 AS BIGINT) tag  -- 為去重后的uuid打上標記司蔬,標記為:0-100之間的整數(shù)沐序。
    FROM detail_sdk_session
    WHERE partition_date >= '2016-01-01' 
      AND partition_date <= now
      AND uuid IS NOT NULL
    GROUP BY uuid   -- 通過GROUP BY琉用,保證去重
   ) t
  GROUP BY tag
) s
;
  1. 第一層SELECT:對uuid進行去重,并為去重后的uuid打上整數(shù)標記
  2. 第二層SELECT:按照標記進行分組策幼,統(tǒng)計每個分組下uuid的個數(shù)
  3. 第三層SELECT:對所有分組進行求和

上面這個方法最關(guān)鍵的是為每個uuid進行標記邑时,這樣就可以對其進行分組,分別計數(shù)特姐,最后去和晶丘。如果數(shù)據(jù)量確實很大,也可以增加分組的個數(shù)唐含。例如:CAST(RAND() * 1000 AS BIGINT) tag

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浅浮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子捷枯,更是在濱河造成了極大的恐慌滚秩,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淮捆,死亡現(xiàn)場離奇詭異郁油,居然都是意外死亡本股,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門桐腌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痊末,“玉大人,你說我怎么就攤上這事哩掺≡涞” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵嚼吞,是天一觀的道長盒件。 經(jīng)常有香客問我,道長舱禽,這世上最難降的妖魔是什么炒刁? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮誊稚,結(jié)果婚禮上翔始,老公的妹妹穿的比我還像新娘。我一直安慰自己里伯,他們只是感情好城瞎,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疾瓮,像睡著了一般脖镀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狼电,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天蜒灰,我揣著相機與錄音,去河邊找鬼肩碟。 笑死强窖,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的削祈。 我是一名探鬼主播翅溺,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼岩瘦!你這毒婦竟也來了未巫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤启昧,失蹤者是張志新(化名)和其女友劉穎叙凡,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體密末,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡握爷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年跛璧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片新啼。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡追城,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出燥撞,到底是詐尸還是另有隱情座柱,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布物舒,位于F島的核電站色洞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冠胯。R本人自食惡果不足惜火诸,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荠察。 院中可真熱鬧置蜀,春花似錦、人聲如沸悉盆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舀瓢。三九已至廷雅,卻和暖如春耗美,著一層夾襖步出監(jiān)牢的瞬間京髓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工商架, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堰怨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓蛇摸,卻偏偏與公主長得像备图,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赶袄,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1.簡介 數(shù)據(jù)存儲有哪些方式揽涮?電子表格,紙質(zhì)文件饿肺,數(shù)據(jù)庫蒋困。 那么究竟什么是關(guān)系型數(shù)據(jù)庫? 目前對數(shù)據(jù)庫的分類主要是...
    喬震閱讀 1,707評論 0 2
  • Hive性能優(yōu)化 1.概述繼續(xù)《那些年使用Hive踩過的坑》一文中的剩余部分敬辣,本篇博客贅述了在工作中總結(jié)Hive的...
    Albert陳凱閱讀 1,513評論 0 8
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法雪标,類相關(guān)的語法零院,內(nèi)部類的語法,繼承相關(guān)的語法村刨,異常的語法告抄,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 【優(yōu)化】COUNT(1)酝锅、COUNT(*)、COUNT(常量)奢方、COUNT(主鍵)搔扁、COUNT(ROWID)、CO...
    小麥苗DB寶閱讀 2,626評論 0 3
  • 幸福是由內(nèi)而外散發(fā)的一種滿足感蟋字,能夠持久稿蹲,沒有壞處,幸福是萬能藥鹊奖。 幸福和快樂有差異苛聘,幸福無法度量,快樂短暫忠聚,可度...
    happness321閱讀 349評論 1 3