为什么需要使用二级索引?
- 对于HBase而言,HBase只能在rowkey上建立索引,如果查询rowkey外的其他列,就需要逐行地比较每一列的值,即进行全表扫描,导致查询效率降低,
- 对于数据量大的表,全表扫描的代价是不可接受的,并且很多情况下不需要从多个角度查询数据。
- Phoenix提供了对HBase的secondary index的支持,secondary index的原理很简单,但是自己维护起来却麻烦一些
Phoenix二级索引分类及特点
全局索引,本地索引,覆盖索引,函数索引
Global Indexing(全局索引)
-
Global indexing,全局索引,适用于==读多写少==的业务场景。
-
使用Global indexing在写数据的时候开销很大,因为所有对数据表的更新操作(DELETE, UPSERT VALUES and UPSERT SELECT),都会引起索引表的更新,而索引表是分布在不同的数据节点上的,跨节点的数据传输带来了较大的性能消耗。
-
在读数据的时候Phoenix会选择索引表来降低查询消耗的时间。
-
在默认情况下如果想查询的字段不是索引字段的话索引表不会被使用,也就是说不会带来查询速度的提升。
-
Local Indexing(本地索引)
-
Local indexing,本地索引,适用于==写操作频繁==以及空间受限制的场景。
-
与Global indexing一样,Phoenix会自动判定在进行查询的时候是否使用索引。
-
使用Local indexing时,索引表的数据和数据表的数据存放在相同的服务器中,这样避免了在写操作的时候往不同服务器的索引表中写索引带来的额外开销。
-
使用Local indexing的时候即使查询的字段不是索引字段索引表也会被使用,这会带来查询速度的提升,这点跟Global indexing不同。对于Local Indexing,一个数据表的所有索引数据都存储在一个单一的独立的可共享的表中。
Covered Index(覆盖索引)
- Covered Index覆盖索引,适用于==一些不参与查询, 但是参与展示字段==构建的场景。
- 与其他索引不同,无法单独使用, 必须结合全局索引或者本地索引共同使用, 大部分一般都是结合全局索引,
- 主要目的将一些不参与查询, 但是参与展示字段构建为覆盖索引, 放置在索引表中, 当查询对应数据的时候, 直接从覆盖索引将相关字段获取到, 避免再次去查询目标表
- 如何构建覆盖索引:
- create [local] index 索引名称 on 表名(列名1, 列名2...) include(覆盖索引字段...)
Functional indexes(函数索引)
- 从Phoeinx4.3以上就支持函数索引,其索引不局限于列,可以合适任意的表达式来创建索引,当在查询时用到了这些表达式时就直接返回表达式结果
- 函数索引不仅允许直接在列上创建索引,还允许通过基于某一列计算值来创建索引。 用法示例如下:
- CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))
其他索引
immutable index(不可变索引)
-
immutable index,不可变索引,适用于数据==只增加不更新并且按照时间先后顺序存储==(time-series data)的场景,如保存日志数据或者事件数据等。
-
不可变索引的存储方式是write one,append only。
-
当在Phoenix使用create table语句时指定IMMUTABLE_ROWS = true表示该表上创建的索引将被设置为不可变索引。
-
不可变索引分为Global immutable index和Local immutable index两种。
-
Phoenix默认情况下如果在create table时不指定IMMUTABLE_ROW = true时,表示该表为mutable。
mutable index(可变索引)
-
mutable index,可变索引,适用于数据有==增删改==的场景。
-
Phoenix默认情况创建的索引都是可变索引,除非在create table的时候显式地指定IMMUTABLE_ROWS = true。
-
可变索引同样分为Global mutable index和Local mutable index两种。