返回介绍

Hive 索引

发布于 2024-06-23 16:10:22 字数 4038 浏览 0 评论 0 收藏 0

Hive是支持索引的,但很少用到。

Hive索引机制

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

在执行索引字段查询时候,首先额外生成一个 MR job,根据对索引列的过滤条件,从索引表中过滤出索引列的值对应的 hdfs 文件路径及偏移量,输出到 hdfs 上的一个文件中,然后根据这些文件中的 hdfs 路径和偏移量,筛选原始input 文件,生成新的 split,作为整个 job 的 split,这样就达到不用全表扫描的目的。

Hive索引建立过程

创建索引

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

之后在 Hive 中会创建一张索引表,也是物理表:
hive索引

其中,索引表中 key 字段,就是原表中 key 字段的值,_bucketname 字段,代表数据文件对应的 HDFS 文件路径,_offsets 代表该 key 值在文件中的偏移量,有可能有多个偏移量,因此,该字段类型为数组。

其实,索引表就相当于一个在原表索引列上的一个汇总表。

生成索引数据

  1. 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;

查询时候索引如何起效:

  1. select * from mapred1234 where key = '13400000144_1387531071_460606566970889';
  • 首先用一个job,从索引表中过滤出key = '13400000144_1387531071_460606566970889' 的记录,将其对应的HDFS文件路径及偏移量输出到HDFS临时文件中
  • 接下来的job中以临时文件为input,根据里面的HDFS文件路径及偏移量,生成新的split,作为查询job的map任务input
  • 不使用索引时候,如下图所示:
    hive索引

    • 表 mapred1234 的每一个 split 都会用一个 map task 去扫描,但其实只有 split2 中有我们想要的结果数据map task1 和 map task3 造成了资源浪费。
  • 使用索引后,如下图所示:
    hive索引

    • 查询提交后,先用一个 MR,扫描索引表,从索引表中找出 key=’xx’ 的记录,获取到 HDFS 文件名和偏移量;
    • 接下来,直接定位到该文件中的偏移量,用一个 map task 即可完成查询,其最终目的就是为了减少查询时候的 input size

手动使用索引

其实就是手动完成从索引表中过滤数据的部分,将过滤出来的数据 load 到 HDFS 临时文件,供查询任务使用。

  1. SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;
  2. Insert overwrite directory "/tmp/mapred1234_index_data"
  3. select `_bucketname`, `_offsets`
  4. from default__mapred_mapred_index__
  5. where key = '13400000144_1387531071_460606566970889';
  6. ##指定索引数据文件
  7. SET hive.index.compact.file=/tmp/ll1_index_data;
  8. SET hive.optimize.index.filter=false;
  9. SET hive.input.format=org.apache.hadoop.hive.ql.index.compact.HiveCompactIndexInputFormat;
  10. select * from mapred1234
  11. where key = '13400000144_1387531071_460606566970889';

从以上过程可以看出,Hive 索引的使用过程比较繁琐:

  • 每次查询时候都要先用一个 job 扫描索引表,如果索引列的值非常稀疏,那么索引表本身也会非常大;
  • 索引表不会自动 rebuild,如果表有数据新增或删除,那么必须手动 rebuild 索引表数据;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文