Hive-如何基於分區優化

最近一直做系統優化,但從建模的角度今天有個小優化,原理比較簡單,效果可能不是很大,但很有意思。

這種優化的好處是不用改變sql代碼,對用戶是透明的。

所以分享下。

-

由於hive在文件基礎上,而會全部掃一個分區裏面的內容。

hive表的概念是基於hadoop的文件系統hdfs,表其實是分佈式文件裏面的一個文件目錄。

再加上沒有索引,如果要取的表裏面的某些字段就必須全部掃描該表對應的文件目錄

-

如:建表way1:

create table if not exists t_hm_0501_test_01

(

uid string,

nick string

)

PARTITIONED BY (pt STRING , bc_seller string )

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 string,

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 及如何確定其分區值

就成了關鍵。

  1. 還可以憑藉一些業務經驗去確定,更科學的是通過系統自動的解決該問題。

這裏通過對hive sql 元數據解析,寫一下算法進行分析,得到更好的提出更優的分區

具體如何選擇需要,需要改字段滿足一些特性。

  1. 比較容易枚舉
  2. 字段指相對固定
  3. 頻率最高的過濾字段

————

如下例子:

如果你在數據分析的過程中,

你的用戶表操作的性別過濾很多,可以以性別作爲分區。

———-

如果你經常分析成交數據

大量分析計算30天的交易成交,其次是60天的成交。

你也可以時段進行分區,這樣可以節省你很多成本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章