Hive-如何基於分割槽優化
最近一直做系統優化,但從建模的角度今天有個小優化,原理比較簡單,效果可能不是很大,但很有意思。
這種優化的好處是不用改變sql程式碼,對使用者是透明的。
所以分享下。
-
由於hive在檔案基礎上,而會全部掃一個分割槽裡面的內容。
hive表的概念是基於hadoop的檔案系統hdfs,表其實是分散式檔案裡面的一個檔案目錄。
再加上沒有索引,如果要取的表裡面的某些欄位就必須全部掃描該表對應的檔案目錄
-
如:建表way1:
create table if not exists t_hm_0501_test_01
(
uid string,
nick string
)
PARTITIONED BY (pt
row format delimited
fields terminated by ‘/t’
lines terminated by ‘/n’
stored as textfile;
-
在hadoop的hdfs中其實是這樣的目錄
–
t_hm_0501_test_01表對應hdfs裡的如下檔案目錄。
/t_hm_0501_test_01
—-
一級分割槽
/t_hm_0501_test_01/pt=20110501000000
/t_hm_0501_test_01/pt=20110502000000
–
二級分割槽
/t_hm_0501_test_01/pt=20110501000000/bc_seller=0
/t_hm_0501_test_01/pt=20110501000000/bc_seller=1
最後那個分割槽目錄後面放的是真正的資料檔案
—
如果有語句 select ,.. from t_hm_0501_test_01 where pt’=20110501000000’ and bc_seller=0
Hadoop只讀取/t_hm_0501_test_01/pt=20110501000000/bc_seller=0 下面的資料,不用處理bc_seller = 1 的資料。
–
如果這個表where條件中的值不是分割槽欄位,則會全部掃裡面的內容。
如果我們把部分常用欄位列舉成分割槽欄位,則會減少掃的內容(條數)。
!!
Way2:
如果這樣建表:
create table if not exists t_hm_0501_test_01
(
uid
nick string
)
PARTITIONED BY (pt STRING )
row format delimited
fields terminated by ‘/t’
lines terminated by ‘/n’
stored as textfile;
-
一級分割槽
/t_hm_0501_test_01/pt=20110501000000
/t_hm_0501_test_01/pt=20110502000000
同樣的sql 語句:
select ,.. from t_hm_0501_test_01 where pt’=20110501000000’ and bc_seller=0
-
其實是掃的是:
/t_hm_0501_test_01/pt=20110501000000 所有東西,包括下面bc_seller=1的資料,增加了髒資料。
浪費了一些map 及其他資源。
-
這其實是一個樹形結構,如果做得好就是個tree演算法,可以最少的讀取檔案。
而且這種優化的好處是不用改變sql程式碼,對使用者是透明的。
那麼如何設定partition 及如何確定其分割槽值
就成了關鍵。
- 還可以憑藉一些業務經驗去確定,更科學的是通過系統自動的解決該問題。
這裡通過對hive sql 元資料解析,寫一下演算法進行分析,得到更好的提出更優的分割槽
具體如何選擇需要,需要改欄位滿足一些特性。
- 比較容易列舉
- 欄位指相對固定
- 頻率最高的過濾欄位
————
如下例子:
如果你在資料分析的過程中,
你的使用者表操作的性別過濾很多,可以以性別作為分割槽。
———-
如果你經常分析成交資料
大量分析計算30天的交易成交,其次是60天的成交。
你也可以時段進行分割槽,這樣可以節省你很多成本。