一起學Hive 之十二 Hive SQL的優化

2021-07-11 15:23:59 字數 2520 閱讀 4583

本章只是從hql層面介紹一下,日常開發hql中需要注意的一些優化點,不涉及hadoop層面的引數、配置等優化。

其中大部分是我之前發過的部落格文章,這裡整理了下。

在select中,只拿需要的列,如果有,盡量使用分割槽過濾,少用select *。

在分割槽剪裁中,當使用外關聯時,如果將副表的過濾條件寫在where後面,那麼就會先全表關聯,之後再過濾,比如:

select a.id

from lxw1234_a a

left outer join t_lxw1234_partitioned b

on (a.id = b.url);

where b.day = 『2015-05-10′

正確的寫法是寫在on後面

select a.id

from lxw1234_a a

left outer join t_lxw1234_partitioned b

on (a.id = b.urland b.day = 『2015-05-10′);

或者直接寫成子查詢

select a.id

from lxw1234_a a

left outer join (select url from t_lxw1234_partitioned where day = 『2015-05-10′) b

on (a.id = b.url)

資料量小的時候無所謂,資料量大的情況下,由於count distinct操作需要用乙個reduce task來完成,這乙個reduce需要處理的資料量太大,就會導致整個job很難完成,一般count distinct使用先group by再count的方式替換:

select day,

count(distinct id) as uv

from lxw1234

group by day

可以轉換成:

select day,

count(id) as uv

from (select day,id from lxw1234 group by day,id) a

group by day;

雖然會多用乙個job來完成,但在資料量大的情況下,這個絕對是值得的。

只要遇到表關聯,就必須得調研一下,是否存在多對多的關聯,起碼得保證有乙個表或者結果集的關聯鍵不重複。

如果某乙個關聯鍵的記錄數非常多,那麼分配到該reduce task中的資料量將非常大,導致整個job很難完成,甚至根本跑不出來。

還有就是避免笛卡爾積,同理,如果某乙個鍵的資料量非常大,也是很難完成job的。

關於mapjoin的原理和機制,請參考 [一起學hive]之十 。

mapjoin中小表的大小可以用引數來調節。

對同一張表的union all 要比multi insert快的多。

具體請見:

用過oracle rac的應該都知道parallel的用途。

並行執行的確可以大的加快任務的執行速率,但不會減少其占用的資源。

在hive中也有並行執行的選項。

具體請見:

如果在hive中執行的sql本身資料量很小,那麼使用本地mr的效率要比提交到hadoop集群中執行快很多。

具體請見:

參見 [一起學hive]之六-hive的動態分割槽

資料傾斜是hive開發中對效能影響的一大殺手。

任務迚度長時間維持在99%(或100%);

檢視任務監控頁面,發現只有少量(1個或幾個)reduce子任務未完成。

本地讀寫資料量很大。

group by, count distinct, join

key分布不均勻

業務資料本身特點

這裡列出一些常用的資料傾斜解決辦法:

使用count distinct和group by造成的資料傾斜:

存在大量空值或null,或者某乙個值的記錄特別多,可以先把該值過濾掉,在最後單獨處理:

select cast(count(distinct imei)+1 as bigint)

from lxw1234 where pt = 『2012-05-28′

and imei <> 『lxw1234′ ;

比如某一天的imei值為』lxw1234』的特別多,當我要統計總的imei數,可以先統計不為』lxw1234』的,之後再加1.

多重count distinct

通常使用union all + row_number() + sum + group by來變通實現。

使用join引起的資料傾斜

關聯鍵存在大量空值或者某一特殊值,如」null」

空值單獨處理,不參與關聯;

空值或特殊值加隨機數作為關聯鍵;

不同資料型別的字段關聯

轉換為同一資料型別之後再做關聯

參見參見 

一起學C 十二

1.while迴圈 while 條件 條件成立時,執行大括號裡的 條件不成立,退出迴圈,執行迴圈下面的語句。從鍵盤接收輸入的字串,如果不是 x 就重複執行,直到收到 x 後退出迴圈,執行 console.readline 接收到回車後結束執行。是等於,是不等於。using system namesp...

一起學Hive 之六 Hive的動態分割槽

前面文章介紹了hive中是支援分割槽的。關係型資料庫 如oracle 中,對分割槽表insert資料時候,資料庫自動會根據分割槽欄位的值,將資料插入到相應的分割槽中,hive中也提供了類似的機制,即動態分割槽 dynamic partition 只不過,使用hive的動態分割槽,需要進行相應的配置。...

一起學Hive 之六 Hive的動態分割槽

hive hive動態分割槽 前面文章介紹了hive中是支援分割槽的。關係型資料庫 如oracle 中,對分割槽表insert資料時候,資料庫自動會根據分割槽欄位的值,將資料插入到相應的分割槽中,hive中也提供了類似的機制,即動態分割槽 dynamic partition 只不過,使用hive的動...