大象教程
首页
Spark
Hadoop
HDFS
MapReduce
Hive
Hive 教程
Hive 教程
Hive 安装(基于Ubuntu系统)
Hive 架构
Hive 内置函数
Hive UDF 简介
Hive DDL 命令
Hive 视图
Hive 索引
Hive Metastore 的三种配置方式
Hive 数据模型
Hive 数据类型
Hive 操作符
Hive SerDe(序列化与反序列化)
Hive 数据分区
Hive 分桶
Hive 分区与分桶的比较
Hive Join 的原理与机制
Hive map Join
Hive bucket map join
#Hive 索引 Hive是支持索引的,但很少用到。 ##Hive索引机制 在指定列上建立索引,会产生一张索引表( Hive 的一张物理表),里面的字段包括,索引列的值、该值对应的 HDFS 文件路径、该值在文件中的偏移量; 在执行索引字段查询时候,首先额外生成一个 MR job,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的 hdfs 文件路径及偏移量,输出到 hdfs 上的一个文件中,然后根据这些文件中的 hdfs 路径和偏移量,筛选原始input 文件,生成新的 split,作为整个 job 的 split,这样就达到不用全表扫描的目的。 ##Hive索引建立过程 ###创建索引 ```sql create index mapred_index on table mapred1234(key) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild; ``` 之后在 Hive 中会创建一张索引表,也是物理表: ![hive索引](/media/editor/file_1574174201000_20191119223641868937.png "hive索引") 其中,索引表中 key 字段,就是原表中 key 字段的值,_bucketname 字段,代表数据文件对应的 HDFS 文件路径,_offsets 代表该 key 值在文件中的偏移量,有可能有多个偏移量,因此,该字段类型为数组。 其实,索引表就相当于一个在原表索引列上的一个汇总表。 ###生成索引数据 ```sql alter index mapred_index on mapred1234 rebuild; ``` 用一个 MR 任务,以 table mapred1234 的数据作为 input,将索引字段 key 中的每一个值及其对应的 HDFS 文件和偏移量输出到索引表中。 ###自动使用索引 SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat; SET hive.optimize.index.filter=true; SET hive.optimize.index.filter.compact.minsize=0; 查询时候索引如何起效: ```sql select * from mapred1234 where key = '13400000144_1387531071_460606566970889'; ``` - 首先用一个job,从索引表中过滤出`key = '13400000144_1387531071_460606566970889'` 的记录,将其对应的HDFS文件路径及偏移量输出到HDFS临时文件中 - 接下来的job中以临时文件为input,根据里面的HDFS文件路径及偏移量,生成新的split,作为查询job的map任务input - 不使用索引时候,如下图所示: ![hive索引](/media/editor/file_1574174444000_20191119224045693305.png "hive索引") - 表 mapred1234 的每一个 split 都会用一个 map task 去扫描,但其实只有 split2 中有我们想要的结果数据map task1 和 map task3 造成了资源浪费。 - 使用索引后,如下图所示: ![hive索引](/media/editor/file_1574174486000_20191119224127429023.png "hive索引") - 查询提交后,先用一个 MR,扫描索引表,从索引表中找出 key=’xx’ 的记录,获取到 HDFS 文件名和偏移量; - 接下来,直接定位到该文件中的偏移量,用一个 map task 即可完成查询,其最终目的就是为了减少查询时候的 input size ##手动使用索引 其实就是手动完成从索引表中过滤数据的部分,将过滤出来的数据 load 到 HDFS 临时文件,供查询任务使用。 ```sql SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat; Insert overwrite directory "/tmp/mapred1234_index_data" select `_bucketname`, `_offsets` from default__mapred_mapred_index__ where key = '13400000144_1387531071_460606566970889'; ##指定索引数据文件 SET hive.index.compact.file=/tmp/ll1_index_data; SET hive.optimize.index.filter=false; SET hive.input.format=org.apache.hadoop.hive.ql.index.compact.HiveCompactIndexInputFormat; select * from mapred1234 where key = '13400000144_1387531071_460606566970889'; ``` 从以上过程可以看出,Hive 索引的使用过程比较繁琐: - 每次查询时候都要先用一个 job 扫描索引表,如果索引列的值非常稀疏,那么索引表本身也会非常大; - 索引表不会自动 rebuild,如果表有数据新增或删除,那么必须手动 rebuild 索引表数据;
加我微信交流吧