性能文章>一起聊一聊hive的索引优化>

一起聊一聊hive的索引优化原创

316244

大家好,我是球球,今天给大家聊聊hive的索引。

索引的作用

Hive从0.7.0版本开始加入了索引,目的是提高Hive表指定列的查询速度。没有索引的时候,Hive在执行查询时需要加载整个表或者整个分区,然后处理所有的数据,但当在指定列上存在索引,再通过指定列查询时,那么只会加载和处理部分文件。此外,同传统关系型数据库一样,增加索引在提升查询速度的同时,会额外消耗资源去创建索引和需要更多的磁盘空间存储索引。Hive支持索引,但是Hive的索引与关系型数据库中的索引并不相同,比如,Hive不支持主键或者外键。

Hive索引可以建立在表中的某些列上,以提升一些操作的效率,例如减少MapReduce任务中需要读取的数据块的数量。

在可以预见到分区数据非常庞大的情况下,索引常常是优于分区的。

虽然Hive并不像事物数据库那样针对个别的行来执行查询、更新、删除等操作。它更多的用在多任务节点的场景下,快速地全表扫描大规模数据。但是在某些场景下,建立索引还是可以提高Hive表指定列的查询速度。(虽然这个效果还不是很好)

索引适用的场景

适用于不更新的静态字段。以免总是重建索引数据。每次建立、更新数据后,都要重建索引以构建索引表。

Hive索引的机制如下:

hive在指定列上建立索引,会产生一张索引表(Hive的一张物理表),里面的字段包括,索引列的值、该值对应的HDFS文件路径、该值在文件中的偏移量;

v0.8后引入bitmap索引处理器,这个处理器适用于排重后,值较少的列(例如,某字段的取值只可能是几个枚举值)

因为索引是用空间换时间,索引列的取值过多会导致建立bitmap索引表过大。

但是,很少遇到hive用索引的,说明还是有缺陷or不合适的地方的,3.0 后hive去掉了索引.

hive索引的机制和原理

Hive的索引其实是一张索引表(Hive的物理表),在表里面存储索引列的值,该值对应的HDFS的文件路径,该值在数据文件中的偏移量。当Hive通过索引列执行查询时,首先通过一个MR Job去查询索引表,根据索引列的过滤条件,查询出该索引列值对应的HDFS文件目录及偏移量,并且把这些数据输出到HDFS的一个文件中,然后再根据这个文件中去筛选原文件,作为查询Job的输入。

优缺点

  • 优点:

    • 可以避免全表扫描和资源浪费
    • 可以加快含有group by的语句的查询速度
  • 缺点:

    • Hive索引的使用过程比较繁琐:

    • 每次查询时候都要先用一个job扫描索引表,如果索引列的值非常稀疏,那么索引表本身也会非常大;

    • 索引表不会自动rebuild,如果表有数据新增或删除,那么必须手动rebuild索引表数据;

索引应用

  • 创建索引
create index index_name
on table base_table_name (col_name, ...)
as 'index.handler.class.name'
[with deferred rebuild]
[idxproperties (property_name=property_value, ...)]
[in table index_table_name]
[partitioned by (col_name, ...)]
[
   [ row format ...] stored as ...   | stored by ...
]
[location hdfs_path]
[tblproperties (...)]
[comment "index comment"]

as ‘index.handler.class.name’ 指定索引处理器,这里的一般使用org.apache.hadoop.hive.ql.index.compact.compactindexhandler 这个处理器。

[with deferred rebuild] 表明创建一个空索引,也就是说现在还不创建索引

[in table index_table_name] 索引存储在哪个表中。

[idxproperties (property_name=property_value, …)] 索引的参数。一般使用idxproperties (‘creator’ = ‘me’,‘created_at’ = ‘some_time’),代表创建者和创建时间。

[partitioned by (col_name, …)]
[
[ row format …] stored as …
| stored by …
]

表明只对某个分区创建索引,若没有该选项则表示对所有分区都创建索引,另外要注意的是index的分区索引默认是和表的分区一致的,也不能对视图view创建索引。

例如:

create index test_index on table test(id)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
in table test;
  • 生成索引数据

刚创建完的Hive索引表是没有数据的,需要生成索引数据

alter index test_index on test rebuild;
  • 显示索引
show index on t_travel_members_m;  

  • 重建数据

建立完索引之后 需要重建索引数据,会触发一个mr job

alter index index_bill_id on  t_travel_members_m rebuild;
  • 使用索引
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;
  • 删除索引
drop index test_index on test;

总结

我们可以发现Hive的索引功能现在还相对较晚,提供的选项还较少。但是,索引被设计为可使用内置的可插拔的java代码来定制,用户可以扩展这个功能来满足自己的需求。当然不是说所有的查询都会受惠于Hive索引。用户可以使用EXPLAIN语法来分析HiveQL语句是否可以使用索引来提升用户查询的性能。像RDBMS中的索引一样,需要评估索引创建的是否合理,毕竟,索引需要更多的磁盘空间,并且创建维护索引也会有一定的代价。用户必须要权衡从索引得到的好处和代价。

 

点赞收藏
分类:标签:
大数据球球

大数据技术布道者

请先登录,查看4条精彩评论吧
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

日常Bug排查-偶发性读数据不一致

日常Bug排查-偶发性读数据不一致

4
4