提高索引查找效率的实践

案例简述

对于一些记录数比较多(数亿条记录)的数据表,在进行增量加载时,如何提高加载效率一直是一个比较难解决的问题,当然这个问题对于OLAP类的系统有一些成熟的解决方案,例如MERGE语句加载,此时数据库会根据数据量自动选择HASH/NESTlOOP的方式,但是对于OLTP类的系统,由于加载时加工的逻辑较为复杂、MERGE占用系统资源较多不好动态调整等原因,仍然需要采用如下方式进行加载:

clip_image002

如何提高这类场景的性能,我们项目组有如下实践。

设计方法说明

上面场景性能较低的原因在于其会产生索引查找操作,而索引查找对应了磁盘的随机读取性能(参考1),每次查找在索引健康(BTREE LEVEL、行迁移等指标正常)的情况下根据索引高度不同,大约对应了3-4次IO操作,而磁盘的随机读通常只有通过在多个磁盘上合理分布数据,然后在磁盘性能允许的情况下提高并发数的方式提高性能。

但是实际上由于开销不单单在于磁盘,还有另外一个方法可以提升性能,就是采用ARRAY技术,ARRAY技术的原理在于一次绑定(BIND)多组数据提交给数据库,以降低数据库客户端和服务器端的交互次数,在实际的测试中,可提高1-2倍的性能。由于此方式不涉及数据表的物理部署修改,也比将应用改造为并发模式要简单,所以是可以优先考虑的一种技术。此外ARRAY方式除了批量业务可以采用外,针对一些场景下的交易系统也可以采用此方法(例如异步交易,也可以采取此方法一次提交一批操作给数据库)。

ARRAY技术的具体实现可以参考资料2。

查询情况下的应用

本文需要重点说明的是在上述技术在查询时的一个变种应用。由于数据库只支持DML时进行批量绑定操作,在查询时无法批量绑定参数,这里可能是由于批量绑定从语义上不是很清晰,批量查询回来的数据,无法一一对应到查询条件中的值。例如我们执行如下伪代码:

SELECT A FROM B=[B1,B2,B3]

数据库返回[A1,A3](这里B2在数据库里不存在),这种情况下应用不知道返回的A值和B值的关系。

所以在具体实现时,我们采用一个变通的方式来实现批量查询,此时我们可以采用一个小技巧,将查询语句从:

SELECT A FROM T1 WHERE B=:b

修改为

SELECT (SELECT A1,B1 FROM T1 WHERE B=:b1),

(SELECT A2,B2 FROM T1 WHERE B=:b2),

(SELECT A3,B3) FROM T1 WHERE B=:b3),

… //共100

FROM DUAL

每次批量将b1,b2,b3…替换为实际的值,这样,从数据库查询回来的结果就直接是KEY和VALUE的多组数据。这里有个需要特别注意的地方,上面的语句如果某一组数据查询不到结果,不会覆盖结果变量(DEFINE VARIABLE)的值,应用需要特殊处理下此处,例如在查询前将变量清空,后面判断如果变量为空就表示查询不到结果。

结语

以上就是我们项目组在数据库使用方面与大家分享的一个小技巧,也适用于一些常见的数据库,例如DB2等。

数据库是一个比较复杂,涉及很多底层细节(例如上面提到的磁盘、存储)的应用软件,同时和我们的日常工作又关系非常密切,很值得从基础开始进行系统的学习,并在实际工作中不断探索,不论是对于数据库应用本身,还是在应用设计时的作为架构

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值