Phoenix二级索引实战

在这里插入图片描述

二级索引

之前的查询,因为没有建立索引,组合条件查询效率较低,而通过使用Phoenix,我们可以非常方便地创建二级索引。Phoenix中的索引,其实底层还是表现为HBase中的表结构。这些索引表专门用来加快查询速度。

索引分类

全局索引

  • 全局索引适用于读多写少业务
  • 全局索引绝大多数负载都发生在写入时,当构建了全局索引时,Phoenix会拦截写入(DELETE、UPSERT值和UPSERT SELECT)上的数据表更新,构建索引更新,同时更新所有相关的索引表,开销较大
  • 读取时,Phoenix将选择最快能够查询出数据的索引表。默认情况下,除非使用Hint,如果SELECT查询中引用了其他非索引列,该索引是不会生效的
  • 全局索引一般和覆盖索引搭配使用,读的效率很高,但写入效率会受影响

创建语法:

CREATE INDEX 索引名称 ON 表名 (列名1, 列名2, 列名3...)

本地索引

  • 本地索引适合写操作频繁,读相对少的业务
  • 当使用SQL查询数据时,Phoenix会自动选择是否使用本地索引查询数据
  • 在本地索引中,索引数据和业务表数据存储在同一个服务器上,避免写入期间的其他网络开销
  • 在Phoenix 4.8.0之前,本地索引保存在一个单独的表中,在Phoenix 4.8.1中,本地索引的数据是保存在一个影子列蔟中本地索引查询即使SELECT引用了非索引中的字段,也会自动应用索引的

注意:创建表的时候指定了SALT_BUCKETS,是不支持本地索引的。
在这里插入图片描述
创建语法:

CREATE local INDEX 索引名称 ON 表名 (列名1, 列名2, 列名3...)

覆盖索引

Phoenix提供了覆盖的索引,可以不需要在找到索引条目后返回到主表。Phoenix可以将关心的数据捆绑在索引行中,从而节省了读取时间的开销。

例如,以下语法将在v1和v2列上创建索引,并在索引中包括v3列,也就是通过v1、v2就可以直接把数据查询出来。

创建语法:

CREATE INDEX my_index ON my_table (v1,v2) INCLUDE(v3)

函数索引

函数索引(4.3和更高版本)可以支持在列上创建索引,还可以基于任意表达式上创建索引。然后,当查询使用该表达式时,可以使用索引来检索结果,而不是数据表。例如,可以在UPPER(FIRST_NAME||‘ ’||LAST_NAME)上创建一个索引,这样将来搜索两个名字拼接在一起时,索引依然可以生效。

-- 创建索引
CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))
-- 以下查询会走索引
SELECT EMP_ID FROM EMP WHERE UPPER(FIRST_NAME||' '||LAST_NAME)='JOHN DOE'

测试函数索引和覆盖索引

select
    *
from
    "MOMO_CHAT"."MSG"
where
        substr("msg_time", 0, 10) = '2022-01-29'
  and "sender_account" = '13514684105'
  and "receiver_account" = '13647128512';

在这里插入图片描述
添加本地索引及函数索引

CREATE LOCAL INDEX LOCAL_IDX_MOMO_MSG ON MOMO_CHAT.MSG(substr("msg_time", 0, 10), "sender_account", "receiver_account");

会发现有以下异常:
在这里插入图片描述
这个时候需要修改hbase-site.xml 文件,支持索引预写日志编码

<!-- 支持索引预写日志编码 -->
<property>
  <name>hbase.regionserver.wal.codec</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCode
</property>

然后需要复制到phoenix这个目录下面一份

cp hbase-site.xml /apache-phoenix-4.13.1-HBase-1.3-bin/bin/

接着重启hbase

./stop-hbase.sh
./start-hbase.sh

重新执行下索引,发现成功了。

在这里插入图片描述
重新执行下这条sql,会发现查询效率提高了。

select
    *
from
    "MOMO_CHAT"."MSG"
where
        substr("msg_time", 0, 10) = '2022-01-29'
  and "sender_account" = '13514684105'
  and "receiver_account" = '13647128512';

在这里插入图片描述
这个时候看下sql的执行计划,会发现走的是range scan,是刚才我们创建的本地索引。

explain select
    *
from
    "MOMO_CHAT"."MSG"
where
        substr("msg_time", 0, 10) = '2022-01-29'
  and "sender_account" = '13514684105'
  and "receiver_account" = '13647128512';

在这里插入图片描述

删除索引

 drop index LOCAL_IDX_MOMO_MSG on MOMO_CHAT.MSG;

在这里插入图片描述

测试全局索引和覆盖索引

select "msg_time" from "MOMO_CHAT"."MSG" where "sender_account" = '13514684105';

在这里插入图片描述

建立一个全局索引并且是覆盖索引

create index IDX_SENDER_ACCOUNT on MOMO_CHAT.MSG("sender_account") include ("id", "msg_time");

在这里插入图片描述
重新来一次搜索,发现速度快多了
在这里插入图片描述

explain select "msg_time" from "MOMO_CHAT"."MSG" where "sender_account" = '13514684105';

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值