Hive索引

Hive是支持索引的,但基本沒用過,只作了下試驗。
爲何你們都不用,確定有它的弊端。apache

Hive索引機制:

在指定列上創建索引,會產生一張索引表(Hive的一張物理表),裏面的字段包括,索引列的值、該值對應的HDFS文件路徑、該值在文件中的偏移量;數組

在執行索引字段查詢時候,首先額外生成一個MR job,根據對索引列的過濾條件,從索引表中過濾出索引列的值對應的hdfs文件路徑及偏移量,輸出到hdfs上的一個文件中,而後根據這些文件中的 hdfs路徑和偏移量,篩選原始input文件,生成新的split,做爲整個job的split,這樣就達到不用全表掃描的目的。oop

 

Hive索引創建過程:

建立索引:

 

 
  1.  
  2. create index lxw1234_index on table lxw1234(key)
  3. as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
  4. with deferred rebuild;

以後在Hive中會建立一張索引表,也是物理表:ui

Hive index Hive索引

Hive index Hive索引spa

 

其中,索引表中key字段,就是原表中key字段的值,_bucketname 字段,表明數據文件對應的HDFS文件路徑,_offsets 表明該key值在文件中的偏移量,有可能有多個偏移量,所以,該字段類型爲數組。orm

其實,索引表就至關於一個在原表索引列上的一個彙總表。索引

生成索引數據

 
  1.  
  2. alter index lxw1234_index on lxw1234 rebuild;

用一個MR任務,以table lxw1234的數據做爲input,將索引字段key中的每個值及其對應的HDFS文件和偏移量輸出到索引表中。hadoop

自動使用索引

 
  1.  
  2. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
  3. SET hive.optimize.index.filter=true;
  4. SET hive.optimize.index.filter.compact.minsize=0;

查詢時候索引如何起效:資源

 
  1.  
  2. select * from lxw1234 where key = '13400000144_1387531071_460606566970889';
  • 首先用一個job,從索引表中過濾出key = ‘13400000144_1387531071_460606566970889’的記錄,將其對應的HDFS文件路徑及偏移量輸出到HDFS臨時文件中
  • 接下來的job中以臨時文件爲input,根據裏面的HDFS文件路徑及偏移量,生成新的split,做爲查詢job的map任務input
  • 不使用索引時候,以下圖所示:Hive index Hive索引

    Hive index Hive索引input

    • table lxw1234的每個split都會用一個map task去掃描,但其實只有split2中有咱們想要的結果數據,map task1和map task3形成了資源浪費。
  • 使用索引後,以下圖所示:Hive index Hive索引

    Hive index Hive索引

    • 查詢提交後,先用一個MR,掃描索引表,從索引表中找出key=’xx’的記錄,獲取到HDFS文件名和偏移量;
    • 接下來,直接定位到該文件中的偏移量,用一個map task便可完成查詢,其最終目的就是爲了減小查詢時候的input size

手動使用索引

    • 其實就是手動完成從索引表中過濾數據的部分,將過濾出來的數據load    到HDFS臨時文件,供查詢任務使用
 
  1.  
  2.  
  3. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
  4.  
  5. Insert overwrite directory "/tmp/lxw1234_index_data"
  6. select `_bucketname`, `_offsets`
  7. from default__lxw1234_lxw1234_index__
  8. where key = '13400000144_1387531071_460606566970889';
  9.  
  10. ##指定索引數據文件
  11. SET hive.index.compact.file=/tmp/ll1_index_data;
  12. SET hive.optimize.index.filter=false;
  13. SET hive.input.format=org.apache.hadoop.hive.ql.index.compact.HiveCompactIndexInputFormat;
  14.  
  15. select * from lxw1234
  16. where key = '13400000144_1387531071_460606566970889';
  17.  

從以上過程能夠看出,Hive索引的使用過程比較繁瑣:

  • 每次查詢時候都要先用一個job掃描索引表,若是索引列的值很是稀疏,那麼索引表自己也會很是大;
  • 索引表不會自動rebuild,若是表有數據新增或刪除,那麼必須手動rebuild索引表數據;
相關文章
相關標籤/搜索