一、分區
簡介
為了對表進行合理的管理以及提高查詢效率,Hive可以將表組織成“分區”。
分區是表的部分列的集合,可以為頻繁使用的數據建立分區,這樣查找分區中的數據時就不需要掃描全表,這對于提高查找效率很有幫助。
分區是一種根據“分區列”(partition column)的值對表進行粗略劃分的機制。Hive中每個分區對應著表很多的子目錄,將所有的數據按照分區列放入到不同的子目錄中去。
為什么要分區?
龐大的數據集可能需要耗費大量的時間去處理。在許多場景下,可以通過分區的方法減少每一次掃描總數據量,這種做法可以顯著地改善性能。
數據會依照單個或多個列進行分區,通常按照時間、地域或者是商業維度進行分區。比如vido表,分區的依據可以是電影的種類和評級,另外,按照拍攝時間劃分可能會得到更一致的結果。為了達到性能表現的一致性,對不同列的劃分應該讓數據盡可能均勻分布。最好的情況下,分區的劃分條件總是能夠對應where語句的部分查詢條件。
Hive的分區使用HDFS的子目錄功能實現。每一個子目錄包含了分區對應的列名和每一列的值。但是由于HDFS并不支持大量的子目錄,這也給分區的使用帶來了限制。我們有必要對表中的分區數量進行預估,從而避免因為分區數量過大帶來一系列問題。
Hive查詢通常使用分區的列作為查詢條件。這樣的做法可以指定MapReduce任務在HDFS中指定的子目錄下完成掃描的工作。HDFS的文件目錄結構可以像索引一樣高效利用。
二、分桶(桶表)
簡介
桶是通過對指定列進行哈希計算來實現的,通過哈希值將一個列名下的數據切分為一組桶,并使每個桶對應于該列名下的一個存儲文件。
為什么要分桶?
在分區數量過于龐大以至于可能導致文件系統崩潰時,我們就需要使用分桶來解決問題了。
分區中的數據可以被進一步拆分成桶,不同于分區對列直接進行拆分,桶往往使用列的哈希值對數據打散,并分發到各個不同的桶中從而完成數據的分桶過程。
注意,hive使用對分桶所用的值進行hash,并用hash結果除以桶的個數做取余運算的方式來分桶,保證了每個桶中都有數據,但每個桶中的數據條數不一定相等。
哈希函數的選擇依賴于桶操作所針對的列的數據類型。除了數據采樣,桶操作也可以用來實現高效的Map端連接操作。
記住,在數據量足夠大的情況下,分桶比分區,更高的查詢效率。
三、總結
分區和分桶最大的區別就是分桶隨機分割數據庫,分區是非隨機分割數據庫。
因為分桶是按照列的哈希函數進行分割的,相對比較平均;而分區是按照列的值來進行分割的,容易造成數據傾斜。
其次兩者的另一個區別就是分桶是對應不同的文件(細粒度),分區是對應不同的文件夾(粗粒度)。
注意:普通表(外部表、內部表)、分區表這三個都是對應HDFS上的目錄,桶表對應是目錄里的文件