Hive提供有限的索引功能,这不像传统的关系型数据库那样有“键(key)”的概念,用户可以在某些列上创建索引来加速某些操作,给一个表创建的索引数据被保存在另外的表中。
Hive的索引功能现在还相对较晚,提供的选项还较少。但是,索引被设计为可使用内置的可插拔的java代码来定制,用户可以扩展这个功能来满足自己的需求。
当然不是说有的查询都会受惠于Hive索引。用户可以使用
EXPLAIN语法来分析HiveQL语句是否可以使用索引来提升用户查询的性能。像RDBMS中的索引一样,需要评估索引创建的是否合理,毕竟,索引需要更多的磁盘空间,并且创建维护索引也会有一定的代价。
用户必须要权衡从索引得到的好处和代价。
创建索引
现在让我们来为分区表employees创建一个索引。首先,然我们再回顾一下employees东侧表定义:
CREATE TABLE employees (
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,state:STRING,zip:INT>
) PARTITIONED BY (country STRING,state STRING);
接着让我们看看如何为该表的contry分区创建索引:
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' = 'some_time')
IN TABLE employees_index_table
PARTITIONED BY (country,name)
COMMENT 'Employees indexed by country and name.';
在本示例中,在employees上创建了名为employees_index的索引,索引数据存放在employees_index_table索引表中,
WITH DEFERRED REBUILD表明创建一个空索引,可以在之后使用如下语句创建索引数据:
ALTER INDEX employees_index ON TABLE employees
PARTITION(country = 'US')
REBUILD;
PARTITIONED BY表明只对某个分区创建索引,若没有该选项则表示对所有分区都创建索引,另外要注意的是index的分区索引默认是和表的分区一致的,也不能对视图VIEW创建索引。
AS 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'表示使用Apache的org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler作为创建索引的handler,当然也可以使用第三方的实现类或其他的实现类。
当然也可以对其他字段创建索引。
Bitmap位图索引
Hive v0.80添加了一个内置的bitmap位图索引。Bitmap位图索引通常适用于只有少数不同值的列创建索引。现在我们修改上一个索引示例为位图索引:
CREATE INDEX employees_index
ON TABLE employees (country)
AS 'BITMAP'
WITH DEFERRED REBUILD
IDXPROPERTIES ('creator' = 'me','created_at' = 'some_time')
IN TABLE employees_index_table
PARTITIONED BY (country,name)
COMMENT 'Employees indexed by country and name.';
重建索引
如果用户在创建索引时指定
WITH DEFERRED REBUILD关键字,那么开始时是一个空索引。我们在任何时候使用
ALTER INDEX语句来创建或重建索引:
ALTER INDEX employees_index ON TABLE employees
PARTITION(country = 'US')
REBUILD;
Hive没有提供一个内置的在数据变更时自动触发创建索引的机制,故用户需要自己通过ALTER INDEX语句来创建索引;另外,重建索引操作是一个原子操作,因此当rebuild失败时,已构建的索引也无法使用。
查看索引
用户可以查看某个表上的所有的索引:
SHOW FORMATTED INDEX ON employees;
SHOW FORMATTED INDEXES ON employees;
删除索引
在删除一个索引的时候,也会同时删除索引数据所在的表,如:
DROP INDEX IF EXISTS employees_index ON TABLE employees;
当然,在删除一个带有索引的表时,索引数据和索引表也会被删除。