phoenix的全局索引没起作用

phoenix的索引表中都会带上原表的主键,即对应hbase的rowkey
对table表的name字段建立全局索引
CREATE INDEX TABLEINDEX ON “table”(“name”);

phoenix里面的全局索引比较废柴,
因为除了select count(*) from table where name=‘xd’
这种写法会用到索引之外,其他的情况都用不到这个全局索引
包括 select * from table where name='xd’也用不到索引,而是进行full scan。

原因分析

这一点和我们平时的sql索引原理有点不一样,普遍理解的是,先去索引表里面可以快速查到name='xd’的数据(因为索引表按name排序),然后根据索引表指针指向,定位到原表的数据,然后在原表中拿出要查询的数据。这是我一直一来对数据库索引的理解。

但是phoenix这里不是这样的,你没有办法通过索引表去查原表,就是这个指针指向的关系给切断了,所以在phoenix里面你每次能用到索引的情况就是你要查询的结果仅仅索引表就可以向你提供。如果涉及到索引表之外的字段,它就不会走索引,而是去原表全局扫描。

基于以上,phoenix建索引最好建覆盖索引,把你最常用到的字段加到include里面去。如下

CREATE INDEX TABLEINDEX ON "table"("name") INCLUDE("column1","column2","column3");

可以看看hbase二级索引的原理

不难发现其中原因,hbase其他二级索引的方案都是在原表中加了一列来区分索引数据和原数据的,尽量设计使索引数据和主数据存储在同一个region中。
而phoenix里面建索引会单独建一张表,对应到hbase中也会多一张表,在hbase的底层存储中,不能保证索引表和原表在同一个region中,所以就没办法根据索引表反向找到原表了。

多条件查询时,建多个独立索引,不如建联合索引

当where后面有多个条件时,若分别在每个条件字段建立单独索引,这些索引并不会全都起作用,系统可能只会选取其中一个索引。
这个时候,对多个条件建立复合索引比较有效。