3、Phoenix二级索引
对于Hbase,如果想精确定位到某行记录,
唯一的办法就是通过rowkey查询。如果不通过rowkey查找数据,
就必须逐行比较每一行的值,对于较大的表,全表扫描的代价是不可接受的。
1、开启索引支持
# 关闭hbase集群
stop-hbase.sh
# 在hbase-site.xml中增加如下配置
phoneix 与 hbase 的都要去设置
<property>
<name>hbase.regionserver.wal.codec</name>
<value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
# 同步到所有节点
scp hbase-site.xml node1:`pwd`
scp hbase-site.xml node2:`pwd`
# 启动hbase
start-hbase.sh
2、创建索引
2.1、全局索引
全局索引适合读多写少的场景。如果使用全局索引,读数据基本不损耗性能,
所有的性能损耗都来源于写数据。数据表的添加、删除和修改都会更新相关的索引表
(数据删除了,索引表中的数据也会删除;数据增加了,索引表的数据也会增加)
注意: 对于全局索引在默认情况下,在查询语句中检索的列如果不在索引表中,
Phoenix不会使用索引表将,除非使用hint。
# 创建DIANXIN.sql
CREATE TABLE IF NOT EXISTS DIANXIN (
mdn VARCHAR ,
start_date VARCHAR ,
end_date VARCHAR ,
county VARCHAR,
x DOUBLE ,
CONSTRAINT PK PRIMARY KEY (mdn)
);
# 上传数据DIANXIN.csv
# 导入数据
psql.py DIANXIN.sql DIANXIN.csv
# 创建全局索引
CREATE INDEX DIANXIN_INDEX ON DIANXIN ( end_date );
# 查询数据 ( 索引未生效)
select * from DIANXIN where end_date = '20180503154014';
# 强制使用索引 (索引生效)
select /*+ INDEX(DIANXIN DIANXIN_INDEX) */ * from DIANXIN where end_date = '20180503154014' and start_date = '20180503154614';
# 取索引列,(索引生效)
select end_date from DIANXIN where end_date = '20180503154014';
# 创建多列索引
CREATE INDEX DIANXIN_INDEX1 ON DIANXIN ( end_date,start_data );
# 多条件查询 (索引生效)
select end_date from DIANXIN where end_date = '20180503154014' and start_date = '20180503154614';
# 查询所有列 ( 索引未生效)
select * from DIANXIN where end_date = '20180503154014' and start_date = '20180503154614';
# 查询所有列 (索引生效)
select /*+ INDEX(DIANXIN DIANXIN_INDEX) */ * from DIANXIN where end_date = '20180503154014' and start_date = '20180503154614';
# 单条件 ( 索引未生效)
select end_date from DIANXIN where start_date = '20180503154614';
2.2、本地索引
本地索引适合写多读少的场景,或者存储空间有限的场景。和全局索引一样,Phoenix也会在查询的时候自动选择是否使用本地索引。本地索引因为索引数据和原数据存储在同一台机器上,避免网络数据传输的开销,所以更适合写多的场景。由于无法提前确定数据在哪个Region上,所以在读数据的时候,需要检查每个Region上的数据从而带来一些性能损耗。
注意:对于本地索引,查询中无论是否指定hint或者是查询的列是否都在索引表中,都会使用索引表。
@ 创建本地索引
CREATE LOCAL INDEX DIANXIN_LOCAL_IDEX ON DIANXIN(grid_id);
# 索引生效
select grid_id from dianxin where grid_id='117285031820040'
# 索引生效
select * from dianxin where grid_id='117285031820040'
2.3、覆盖索引
覆盖索引是把原数据存储在索引数据表中,这样在查询时不需要再去HBase的原表获取数据就,直接返回查询结果。
注意:查询是 select 的列和 where 的列都需要在索引中出现。
# 创建覆盖索引
CREATE INDEX DIANXIN_INDEX_COVER ON DIANXIN ( x,y ) INCLUDE ( county );
# 查询所有列 (索引未生效)
select * from dianxin where x=117.288 and y =31.822;
# 强制使用索引 (索引生效)
select /*+ INDEX(DIANXIN DIANXIN_INDEX_COVER) */ * from dianxin where x=117.288 and y =31.822;
# 查询所索引中的列 (索引生效)
select x,y,county from dianxin where x=117.288 and y =31.822;