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;
当然,在删除一个带有索引的表时,索引数据和索引表也会被删除。