1. 程式人生 > >HIVE—索引、分割槽和分桶的區別

HIVE—索引、分割槽和分桶的區別

一、索引

Hive支援索引,但是Hive的索引與關係型資料庫中的索引並不相同,比如,Hive不支援主鍵或者外來鍵。

Hive索引可以建立在表中的某些列上,以提升一些操作的效率,例如減少MapReduce任務中需要讀取的資料塊的數量。

為什麼要建立索引?

Hive的索引目的是提高Hive表指定列的查詢速度。

沒有索引時,類似'WHERE tab1.col1 = 10' 的查詢,Hive會載入整張表或分割槽,然後處理所有的rows

但是如果在欄位col1上面存在索引時,那麼只會載入和處理檔案的一部分。

與其他傳統資料庫一樣,增加索引在提升查詢速度時,會消耗額外資源去建立索引表和需要更多的磁碟空間儲存索引。

二、分割槽

簡介

為了對錶進行合理的管理以及提高查詢效率,Hive可以將表組織成“分割槽”。

分割槽是表的部分列的集合,可以為頻繁使用的資料建立分割槽,這樣查詢分割槽中的資料時就不需要掃描全表,這對於提高查詢效率很有幫助。

分割槽是一種根據“分割槽列”(partition column)的值對錶進行粗略劃分的機制。Hive中每個分割槽對應著表很多的子目錄,將所有的資料按照分割槽列放入到不同的子目錄中去。

為什麼要分割槽?

龐大的資料集可能需要耗費大量的時間去處理。在許多場景下,可以通過分割槽的方法減少每一次掃描總資料量,這種做法可以顯著地改善效能。

資料會依照單個或多個列進行分割槽,通常按照時間、地域或者是商業維度進行分割槽。比如vido

表,分割槽的依據可以是電影的種類和評級,另外,按照拍攝時間劃分可能會得到更一致的結果。為了達到效能表現的一致性,對不同列的劃分應該讓資料儘可能均勻分佈。最好的情況下,分割槽的劃分條件總是能夠對應where語句的部分查詢條件。

Hive的分割槽使用HDFS的子目錄功能實現。每一個子目錄包含了分割槽對應的列名和每一列的值。但是由於HDFS並不支援大量的子目錄,這也給分割槽的使用帶來了限制。我們有必要對錶中的分割槽數量進行預估,從而避免因為分割槽數量過大帶來一系列問題。

Hive查詢通常使用分割槽的列作為查詢條件。這樣的做法可以指定MapReduce任務在HDFS中指定的子目錄下完成掃描的工作。HDFS

的檔案目錄結構可以像索引一樣高效利用。

三、分桶(桶表)

桶是通過對指定列進行雜湊計算來實現的,通過雜湊值將一個列名下的資料切分為一組桶,並使每個桶對應於該列名下的一個儲存檔案。

為什麼要分桶?

在分割槽數量過於龐大以至於可能導致檔案系統崩潰時,我們就需要使用分桶來解決問題了。

分割槽中的資料可以被進一步拆分成桶,不同於分割槽對列直接進行拆分,桶往往使用列的雜湊值對資料打散,並分發到各個不同的桶中從而完成資料的分桶過程。

注意,hive使用對分桶所用的值進行hash,並用hash結果除以桶的個數做取餘運算的方式來分桶,保證了每個桶中都有資料,但每個桶中的資料條數不一定相等。

雜湊函式的選擇依賴於桶操作所針對的列的資料型別。除了資料取樣,桶操作也可以用來實現高效的Map端連線操作。

記住,在資料量足夠大的情況下,分桶比分割槽,更高的查詢效率。

四、總結

索引和分割槽最大的區別就是索引不分割資料庫,分割槽分割資料庫。

索引其實就是拿額外的儲存空間換查詢時間,但分割槽已經將整個大資料庫按照分割槽列拆分成多個小資料庫了。

分割槽和分桶最大的區別就是分桶隨機分割資料庫,分割槽是非隨機分割資料庫。

因為分桶是按照列的雜湊函式進行分割的,相對比較平均;而分割槽是按照列的值來進行分割的,容易造成資料傾斜。

其次兩者的另一個區別就是分桶是對應不同的檔案(細粒度),分割槽是對應不同的資料夾(粗粒度)。

注意:普通表(外部表、內部表)、分割槽表這三個都是對應HDFS上的目錄,桶表對應是目錄裡的檔案