Cobar提出的一种在分库场景下对Order By / Limit 的优化

简介: Cobar 虽然是一款“古老”的数据库中间件,但目前不少公司仍然在用它,且它包含了不少有意思的算法和实现,今天就来分享 Cobar 提出的一种在分库场景下对 Order By / Limit 的优化。

背景


Cobar 最重要的功能就是分库分表,通常读取性能瓶颈可以通过增加从库或缓存来解决。

但写入性能在 MySQL 上只能通过分库分表来提升。


当我们把数据分布到不同的数据库上时,再查询时如果是单条数据只要找到这条数据对应的库即可,但如果是多条数据,可能分布在不同的库上时,Cobar 就需要先查询,再聚合。


2379072-20211012104055892-1397745960.png

来个具体例子:


2379072-20211012104101214-1144897301.png


如果我们要查询 tb1 表的 c1 字段,且取 c1 正序的下标(从0开始)为4、5的数据。假设分了三个库,我们为了取到正确数据,需要去这三个分库都取下标0-5的数据,假设取到如下数据:


2379072-20211012104106587-1710740393.png


取到3堆已排序的数据,对这3堆数据从小开始丢弃0、1、2、3号数据,保留第4、5号数据即是我们需要的。



2379072-20211012104112938-1160795677.png


个算法看起来没啥问题,但如果数据量稍微变化一下,比如:


select c1 from tb1 order by c1 limit 9999999, 4


如果还按照上述的方法来做,首先得去每个分库查询 0 - 10000003的数据,然后再合并丢弃0-9999998号数据。


相当于丢弃了大约不分库时3倍的数据。这多少显得有点浪费了。


算法优化


  • Step1:将这条语句拆分成3条语句发给3个分库:


2379072-20211012104119589-1746924656.png


  • Step2:找出查询结果的最大和最小值,这里假设最小值为3,最大值为11


2379072-20211012104124665-957132148.png


  • Step3:以最小值和最大值为条件再次查询


2379072-20211012104129599-882464228.png


假设我们取得的数据如图,那么我们是不是很容易推断出这些结果之前还有多少数据?


  • Step4:反查出每一个返回结果的 offset,这里我们就能推断出分库1在最小值之前还有3333332条数据,分库2在最小值之前还有3333333条数据,分库3在最小值之前还有3333331条数据


2379072-20211012104135347-1074554472.png

这时,我们就可以丢弃合并后的0-9999998号数据了,分库1、2、3将最小值之前的数据都丢弃共丢弃了0-9999995号数据,再丢弃3个最小值3刚好够到了9999998,所以9999999号数据开始依次是4、5、5、6


2379072-20211012104144079-157780039.png


算法分析


效率


以上例来说明,未优化前:


  • 1次查询,查询的数据总量大约 3kw,丢弃9999999条数据


优化后:


  • 第1次查询,查询数据总量约 1kw
  • 第2次查询,数据总量17
  • 丢弃3条数据


从这个例子可以看出,查询的数据量大大减少,需要计算丢弃的量也大大减少


非理想情况


可能大家能看出来,上述例子是非常理想的情况,如果数据没这么“理想”,结局又是怎样?


  • Step4 中反查的最小值之前不够丢弃怎么办,比如:


2379072-20211012104150287-1437006913.png


  • Step4 中反查的最小值之前的数据比需要丢弃的数据多怎么办?


2379072-20211012104155109-1288761434.png


可以看出,如果是这两种情况,这种算法就没法再次生效了。


优化的前提


根据上述两种情况来看,可以总结出该算法生效的前提是:


数据(排序字段)在各个分库上的分布要均匀


其实可以做个极端的假设,比如只有第一个分库上有数据,其他数据库没有数据,那么这个算法就失效了


总结


这么来看,这个算法是不是很废?确实比较废,就连 Cobar 中也没有使用。


但在某些场景下还是有比较大的提升的,分库的数据大部分时候是按字段进行取模,所以可以认为几乎是分布均匀的,此时如果 Order By / Limit 是比较深度翻页的数据,可以采取此策略,但也要进行兜底,如果返回的数据不满足条件,继续退化为最初的算法,所以单次效率可能不高,但从统计值上来看其效率可能是更高的。














相关文章
|
Java Python Spring
spring + groovy 实现动态代码注入执行
spring + groovy 实现动态代码注入执行
5659 0
|
安全 开发者
苹果应用上架是否需要软件著作权?
根据苹果公司的规定,如果想要上传应用到App Store上,必须进行软著申请并获得软著证书。这是因为苹果公司希望保证上传到App Store上的应用都是合法合规的,软著证书可以证明应用的合法性和作者的权益。
|
3月前
|
人工智能 安全 API
2026年OpenClaw AI Agent 潜力解锁指南:必装Skill+阿里云/Windows部署OpenClaw全流程
很多人使用OpenClaw后都会有同一个困惑:为什么别人的“小龙虾”既能联网查实时资讯、自动执行定时任务,甚至能实现自动化交易赚钱,而自己的却“又呆又笨”——定时任务触发失败、查不到最新信息、只能被动回应简单指令?
2125 1
|
2月前
|
设计模式 人工智能 安全
OpenClaw 13000+ Skills 怎么选?这 30 个最值得装(附 5 个必装 Skill)
本文深度解析OpenClaw万级Skill生态:厘清Skill、Prompt、Agent本质区别,直击安全风险(如API密钥泄露),系统梳理8大高价值场景,并推荐新手必装5个核心Skill。附Skill架构、设计模式与AI Agent OS演进路径,助你科学选型、安全落地。
|
2月前
|
人工智能 Linux API
保姆级教程:OpenClaw阿里云、MacOS、Linux、Windows11部署+百炼API配置+集成截图Skill及避坑指南
OpenClaw(原Clawdbot)作为一款开源的AI自动化代理工具,凭借自然语言驱动的任务执行能力,成为提升工作效率的核心工具,但其本地部署的环境配置、大模型对接难题,以及默认仅支持文字交互的视觉盲区,让零基础新手难以发挥其全部能力。2026年针对这些痛点,本文整理了阿里云、MacOS、Linux、Windows11多平台的OpenClaw本地部署完整步骤,详解阿里云百炼免费大模型API配置方法,同时带来能解决AI视觉盲区的Screenshot技能集成教程,并对部署和使用中的常见问题逐一解答,让新手也能零门槛实现OpenClaw的全功能使用。
1461 14
|
Java API Apache
阿里巴巴开源框架JarsLink
JarsLink是一个基于JAVA的模块化开发框架,它提供在运行时动态加载模块(JAR包)、卸载模块和模块间调用的API,它能够帮助你进行模块化开发,也能帮助你的系统在运行时动态添加新功能,减少编译、打包和部署带来的发布耗时,同时它也是阿里巴巴的开源项目之一 https://github.com/alibaba/jarslink,目前在微贷事业群各团队广泛使用。
15079 0
|
传感器 机器学习/深度学习 弹性计算
Agent与大模型的区别
本文详细对比了人工智能领域的两个重要概念——Agent和大模型。大模型如GPT-3、BERT等,擅长自然语言处理任务,如文本生成、翻译等;Agent则是自主的软件实体,能够在特定环境中感知、决策并执行任务,如管理日程、控制智能家居等。文章介绍了它们的定义、功能、技术架构及应用场景,并总结了两者的核心差异和未来发展方向。
14553 26
|
存储 缓存 监控
StarRocks面试题及答案整理,最新面试题
StarRocks面试题及答案整理,最新面试题
1653 0
|
存储 消息中间件 缓存
本地缓存之王,Caffeine保姆级教程
本地缓存之王,Caffeine保姆级教程
11834 1

热门文章

最新文章