1.简介
Hive在0.7.0版本开始加入索引。Hive中的索引和关系型数据库中的索引又有些不同。例如:Hive中没有关系型数据库中键的概念。
在Hive中有逻辑分区,而建立索引也是成为分区的另一种选择。建立索引可以帮助裁掉一张表的一些数据块,这样能够减少MapReduce的输入数据量。但并不是所有的查询都可以通过建立索引来获得查询速度。
Hive中使用索引和关系型数据库中使用数据库一样,都需要进行仔细评估。因为索引其实是用空间换时间,所以用户需要权衡一下空间和时间之间的损失代价再做选择。
2.创建索引
首先创建一个employees表,代码如下:
CREATE TABLE employees(
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:STRING
) PARTITIONED BY (country STRING , state STRING);
下面是对分区字段country建立索引:
hive> create index employees_index
on table employees(country)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
idxproperties ('creator'='me','created_at'='2017-2-13')
in table employees_index_table
partition by (country,name)
comment 'Employees indexed by country and name.';
在这种情况下,我们没有像原表那样对索引表进行同一粒度的分区划分。其实我们是可以那么做的。如果我们完全省略掉队 RTITIONED BY 语句的话,那么索引将会包含原始表的所有分区。
AS语句指定了索引处理器,也就是一个实现了索引接口的Java类。Hive中的索引处理模块被设计成为可以定制的Java编码的插件,所以用户可以根据需求对其实现,以满足自身的需求。当然Hive本身就会提供一些典型的索引实现。CompactIndexHandler就是其中一种比较常用的。
Comment是对所创建的索引的描述,写描述就和写代码注释是一样的,是程序员必须养成的一个好习惯,对以后理解代码是有帮助的。
在Hive中视图和外部表都可以建立索引的。
2.1 CompactIndexHandler
通过将列中相同的值得字段进行压缩从而减小存储和加快访问时间。需要注意的是Hive创建压缩索引时会将索引数据也存储在Hive表中。对于表tb_index (id int, name string) 而言,建立索引后的索引表中默认的三列一次为索引列(id)、hdfs文件地址(_bucketname)、偏移量(offset)。特别注意,offset列类型为array。
2.2 Bitmap
Hive0.8版本开始引入位图索引,位图索引作为一种常见的索引,如果索引列只有固定的几个值,那么就可以采用位图索引来加速查询,利用位图索引可以方便的进行AND/OR/XOR等各类计算。
hive> create index employees_index
on table employees (country)
as 'Bitmap'
idxproperties ('creator'='me','created_at'='2017-02-13')
in table employees_index_table
partitioned by (country,name)
comment 'Employees indexed by country and name.';
3.重建索引
如果用户指定了DEFERRED REBUILD,那么新创建额索引将呈现空白状态,里面并没有数据,需要使用ALTER INDEX对索引进行重建:
hive> alter index employees_index
on table employees
partition (country='US')
rebuild;
如果省略partition,那么二将会对所有分区进行重建索引。
注意:
1.当Hive数据更新时,必须调用该语句更新索引。
2.如果重建索引失败,那么在重建开始之前,索引将停留在之前的版本状态。所以重建索引操作做是原子性的。
4.显示索引
SHOW FORMATTED INDEX ON employees;
用上面这个命令可以显示这个索引表对所有列所简历的索引。
FORMATTED关键字是可选的,这个关键字可以使输出中包含列名称。
INDEX关键字也是可以替换INDEXES,这样输出中就可以列举出多个索引信息了。
想要索引在查询时,生效,还得设置使用索引:默认是不使用的。
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;
5.删除索引
DROP INDEX IF EXISTS employees_index ON TABLE employees;
Hive 不允许用户直接使用 DROP TABLE 语句之前删除索引表。而通常情况下, IF EXISTS 都是可选的,其用于当索引不存在时避免抛出错误信息。
如果被索引的表被删除了,那么其对应的索引和索引表也会被删除。同样地,如果原始表的某个分区被删除了,那么这个分区对应的分区索引也同时会被删除掉。
6.缺点
- 使用过程繁琐
- 需要额外Job扫描索引表
- 不会自动刷新,如果表有数据变动,索引表也需要手动刷新。