Hive索引


Hive是支持索引的,但基本沒用過,只做了下試驗。
為什么大家都不用,肯定有它的弊端。

Hive索引機制:

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

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

 

Hive索引建立過程:

創建索引:

 

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

之后在Hive中會創建一張索引表,也是物理表:

Hive index Hive索引

Hive index Hive索引

 

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

其實,索引表就相當於一個在原表索引列上的一個匯總表。

生成索引數據

 
 
 
         
  1. alter index lxw1234_index on lxw1234 rebuild;

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

自動使用索引

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

查詢時候索引如何起效:

 
 
 
         
  1. 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索引

    • 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. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
  3.  
  4. Insert overwrite directory "/tmp/lxw1234_index_data"
  5. select `_bucketname`, `_offsets`
  6. from default__lxw1234_lxw1234_index__
  7. where key = '13400000144_1387531071_460606566970889';
  8. ##指定索引數據文件
  9. SET hive.index.compact.file=/tmp/ll1_index_data;
  10. SET hive.optimize.index.filter=false;
  11. SET hive.input.format=org.apache.hadoop.hive.ql.index.compact.HiveCompactIndexInputFormat;
  12.  
  13. select * from lxw1234
  14. where key = '13400000144_1387531071_460606566970889';
  15.  

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

  • 每次查詢時候都要先用一個job掃描索引表,如果索引列的值非常稀疏,那么索引表本身也會非常大;
  • 索引表不會自動rebuild,如果表有數據新增或刪除,那么必須手動rebuild索引表數據;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM