【Hive】一次被分区条件和笛卡尔积制裁的经历
記錄一下之前遇到的一個問題:一張幾百T按天dt分區的訂單表,要關聯一張幾M的訂單類型快照表,逐月分析。
因為用的時候left join,所以訂單表放在了左邊,但是hive中如果要將兩張表join起來的話,大表放在左邊效率會比較低,如果所有表中只有一張表是小表,那么可以在最大的表通過mapper的時候將小表完全放到內存中。
Hive可以在map端執行連接過程,稱為map-side JOIN,這是因為Hive可以和內存中內存中的小表進行逐一匹配,從而省略掉常規連接操作所需要的reduce過程。即使對于很小的數據集,這個優化也明顯地要快于常規的連接操作,不僅減少了reduce過程,而且有時還可以同時減少map過程的執行步驟。
想要使用這個優化可以設置屬性hive.auto.convert.JOIN的值為true:
-- 演示代碼,無實際業務 set hive.auto.convert.join=true;create table res_table as selecta.*,b.type from ((select*fromorder_tablewhereuser_id is not null and user_id <> ''and dt >= '2021-07-01'and dt <= '2021-07-31') as aleft join (select*fromorder_type_table) as bon a.type_id = b.type_id; )但是不知道為啥,執行的效率還是很滿,只要join表就的花個三個小時左右,我尋思也不應該啊,我每次只取了一個月的訂單數據,已經加了優化,怎么可能還跑那么久。
于是沒辦法,只能去求助mentor,結構被一眼打回來了,a表的where篩選條件有問題,因為是dt分區表,所以應該先篩選dt,然后再判斷user_id不為空。
使用dt分區表時where篩選條件中分區字段要放在前面
改完了之后,能跑是能跑了,而且幾分鐘就跑完了,map和reduce都到了100%,但是最后要把數據寫到表里的時候卻巨慢無比,又花了好幾個小時。
結果我一看數據,我的天,不太對勁,本來a表只有幾億條記錄,結果寫入res_table之后一下變成十幾億條記錄,這妥妥的是產生笛卡爾積了啊。
然后看了一篇文章:left join 與join都會形成笛卡爾積
確認了一下,確實是產生笛卡爾積了,但是type_id應該是唯一的啊,一問才知道,原來b表是快照表,限制最新分區,我沒卡dt,所以才產生了笛卡爾積。
最后改完就好啦:
-- 演示代碼,無實際業務 set hive.auto.convert.join=true;create table res_table as selecta.*,b.type from ((select*fromorder_tablewheredt >= '2021-07-01'and dt <= '2021-07-31' and user_id <> ''and user_id is not null) as aleft join (select*fromorder_type_tablewheredt = '2021-07-01') as bon a.type_id = b.type_id; ) 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Hive】一次被分区条件和笛卡尔积制裁的经历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5.3 个体条件期望(Individua
- 下一篇: Linux磁盘空间被占满?清空回收站试试