ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

OceanBase 和金仓怎么选?别只看分布式,复杂查询更考验架构取舍

OceanBase 和金仓怎么选?别只看分布式,复杂查询更考验架构取舍 OceanBase 和金仓怎么选别只看分布式复杂查询更考验架构取舍去年碰巧接触了两个数据库选型项目。一个最后选了 OceanBase另一个用了金仓 KingbaseES。两个项目差别其实挺大。前者数据规模已经到了几 TB业务并发高而且后面还要继续扩容后者是比较典型的企业 ERP数据量不到 1TB更关注迁移成本、SQL 兼容和日常运维。有意思的是两个项目上线以后客户反馈都不错。这件事后来让我对数据库选型这件事有了一个更明确的看法数据库很难简单地分成“谁比谁强”更多时候是在看你的业务更适合哪种架构。OceanBase 原生就是冲着分布式去的节点越多扩展空间越大。KingbaseES 则更接近传统企业熟悉的关系型数据库使用方式集中式、主备、高可用这些场景比较自然。如果当前业务量还没大到必须拆到多节点集中式架构反而可能更简单。这篇不准备单纯比跑分主要聊一个更实际的问题为什么同样一条 SQL到了集中式和分布式数据库里执行方式会完全不一样先把一个问题说清楚分布式并不等于“每条 SQL 都更快”很多人第一次接触分布式数据库容易形成一个直觉三台机器肯定比一台机器快。但数据库不是这么算的。如果任务本身可以很好地拆开比如大表扫描、分区聚合、海量数据并行计算多节点确实可以一起干活。但如果是一条跨表很多、关联关系复杂的 SQL事情就不一样了。假设有三台节点。订单表的一部分在节点 A客户表在节点 B商品信息又在节点 C。这时候执行一条 JOIN不只是 CPU 做计算还可能出现定位数据 → 节点间传输 → 数据重新分布 → 局部计算 → 汇总结果 → 返回客户端这里任何一个环节都会有成本。而集中式数据库里数据主要在一个实例内部完成读取、过滤、排序和 JOIN。少了跨节点通信以后很多中小规模查询反而更直接。所以两种架构真正的区别不是分布式 快 集中式 慢而更像分布式拿额外的协调成本换扩展能力 集中式拿规模上限换更简单的执行路径这两个选择本身都没有问题。关键看你的系统到底需要什么。OceanBase 为什么更适合“大规模”OceanBase 从架构设计上就是分布式数据库。每个节点都有自己的计算、内存和存储资源数据按照一定规则分布到不同节点同时通过副本机制保证可靠性。它最大的价值其实不是“某一条 SELECT 比别人快多少”。而是当一台机器撑不住的时候还可以继续往外扩。例如一个电商系统早期每天几百万订单后面涨到几千万甚至更高。集中式数据库可能需要不断升级 CPU、内存和存储。硬件规模到一定程度以后继续纵向升级会越来越贵。分布式数据库则可以通过增加节点把数据和计算继续拆出去。这也是 OceanBase 比较擅长的地方。对于互联网业务来说这个能力很重要。因为很多时候你解决的不是现在这一条 SQL 能不能再快 50ms而是三年以后数据翻十倍这套数据库还能不能继续扛从这个角度来看OceanBase 的价值很清楚。金仓更像传统企业数据库的“熟悉路线”另一个项目使用的是 KingbaseES。这个项目本身没有特别夸张的数据规模。大约几百 GB 数据日常业务以 ERP、报表、订单和后台管理为主并发量也没有到互联网平台那种级别。这种系统真正关心的东西反而比较传统SQL 能不能直接迁存储过程要改多少原来的 DBA 能不能维护主备怎么切换出了问题怎么恢复这时候集中式数据库的优势就出来了。业务请求进入数据库以后大部分操作都发生在本地实例内部。查询、JOIN、排序、聚合不需要为了“分布式”额外跨节点。对于几百 GB 到 TB 级的数据只要硬件合理、索引设计正常很多企业系统根本没必要把查询拆到多节点。这也是为什么我们那个 ERP 项目最终没有为了“架构先进”强行上分布式。技术方案不是越复杂越好。能够用两台机器解决的问题没必要为了架构图好看上六台。真正能看出差别的是复杂 JOIN简单主键查询其实没太多可比性。例如SELECT*FROMordersWHEREorder_id10001;索引正常的时候主流数据库基本都不会太差。真正容易把架构差异暴露出来的是复杂查询。例如下面这种SELECTo.order_id,o.customer_id,c.customer_name,p.product_name,oi.quantity,oi.priceFROMorders oJOINcustomers cONo.customer_idc.customer_idJOINorder_items oiONo.order_idoi.order_idJOINproducts pONoi.product_idp.product_idWHEREo.order_date2026-01-01ANDo.statuscompletedORDERBYo.order_dateDESCLIMIT100;这类 SQL 在 ERP、BI 和数据分析系统里很常见。集中式数据库处理它的时候优化器主要考虑哪张表先过滤JOIN 顺序怎么排走哪个索引用 Hash Join 还是 Nested Loop中间结果要不要排序是否需要并行执行这些操作主要发生在单个数据库实例内部。但如果换成分布式环境还多了一个问题数据到底在哪台机器上假设orders → 节点 A、B、C customers → 节点 A、B、C order_items → 节点 A、B、C products → 节点 A、B、C如果几张表的数据分布键正好和关联键一致那很好。数据可以本地 JOIN。但如果不一致就可能出现数据重分布。例如订单按照order_id分区客户按照customer_id分区。做orders.customer_idcustomers.customer_id时数据库可能需要把部分订单数据重新发到对应客户所在节点。这就是分布式数据库经常提到的 Shuffle 或数据重分布。一旦数据量大起来网络就会参与整个执行过程。所以分布式复杂查询的性能不只是取决于 SQL 怎么写。表怎么分区同样重要。一条 SQL 快不快有时候在建表那天就已经决定了一半这也是我后来做分布式数据库项目感触比较深的一点。传统数据库里开发人员最常考虑的是索引。例如CREATEINDEXidx_orders_customerONorders(customer_id);到了分布式数据库还得多考虑一个问题这张表到底按照什么字段分布如果分布键选对了大量查询都可以在本地完成。如果选错了同一条业务链路可能不断跨节点。举个例子。一个订单系统最主要的查询方式是WHEREcustomer_id?而且大量 JOIN 都是orders.customer_idcustomer.customer_id那按照customer_id去做数据分布通常比较自然。但如果一开始按照其他字段拆后面大量查询都可能发生跨节点访问。所以分布式数据库有一个很现实的问题前期架构设计比集中式数据库更重要。因为有些坑不是后来加一个索引就能完全补回来的。嵌套子查询也是优化器的一道考试题再看一个实际系统很容易出现的 SQLSELECTorder_id,customer_id,amount,(SELECTCOUNT(*)FROMorder_items oiWHEREoi.order_ido.order_id)ASitem_count,(SELECTSUM(amount)FROMpayments pWHEREp.order_ido.order_id)AStotal_paymentFROMorders oWHEREorder_date2026-01-01;这种代码开发人员很爱写。因为直观。一眼就能看出来订单数量、商品数量、支付金额。但数据库最怕“看起来直观实际执行很贵”。如果最外层查出了 10 万条订单而里面的子查询每一行都重新跑一次那代价就大了。好的优化器会尝试把这类 SQL 改写。比如把相关子查询改成聚合 JOIN让原来可能执行几万次的子查询变成一次数据扫描。集中式数据库做这种改写相对直观。分布式数据库则还需要继续判断聚合放在哪个节点能不能下推结果在哪里汇总JOIN 会不会重新分布因此同一条 SQL在两种架构下看到的执行计划可能差别很大。这也是为什么我现在做数据库选型基本不会只测试简单 CRUD。复杂 SQL 才更容易看到数据库真正的能力。窗口函数也是同样的道理比如SELECTorder_id,customer_id,amount,ROW_NUMBER()OVER(PARTITIONBYcustomer_idORDERBYorder_dateDESC)ASrn,SUM(amount)OVER(PARTITIONBYcustomer_idORDERBYorder_dateROWSBETWEENUNBOUNDEDPRECEDINGANDCURRENTROW)ASrunning_totalFROMordersWHEREorder_date2026-01-01;这种 SQL 对数据库来说本质上绕不开几个动作过滤 → 分区 → 排序 → 窗口计算集中式环境下这些数据如果能在单机内存和磁盘之间完成处理路径比较清晰。分布式环境如果恰好按照customer_id分布问题也不大。但如果数据分布方式和窗口函数的PARTITION BY对不上就可能需要先重新分发数据再进行计算。所以还是回到那个问题分布式数据库不是复杂查询一定慢而是复杂查询对数据分布更加敏感。这句话比直接说“集中式复杂查询更快”要准确得多。我后来已经不太喜欢直接比毫秒了以前做数据库测试我也喜欢整理成这种表数据库查询耗时A600msB800ms看起来特别直观。后来项目做多了发现这种表如果没有上下文其实意义不大。因为至少要说明CPU 是否相同 内存是否相同 磁盘是否相同 数据规模是否相同 并发数是多少 缓存是否预热 索引是否一致 统计信息是否准确 并行度是多少 数据如何分区 SQL 是否完全一样任何一个变量改变结果都可能翻过来。甚至同一个数据库第一次3.2 秒第二次400ms都有可能。因为第一次从磁盘读第二次已经命中缓存。所以现在我更愿意看P50 P95 P99 吞吐量 CPU IOPS 网络流量 执行计划而不是只截一条 SQL 跑一次然后宣布谁更快。运维成本其实比性能更容易被低估两个项目做下来我觉得数据库选型还有一个经常被忽视的问题谁来维护OceanBase 的分布式架构优势很明显但相应地需要理解的东西也更多。例如节点 Zone 副本 Leader 分区 数据分布 租户 资源隔离 跨节点事务如果团队本身就有比较成熟的数据库平台团队这些问题不算什么。但如果公司只有一两个 DBA还同时维护 Oracle、MySQL、Redis、Kafka再上一套分布式数据库学习和运维成本就得认真算进去。集中式数据库通常更符合传统 DBA 的经验模型。例如主库 备库 WAL/日志 流复制 连接池 索引 SQL优化 备份恢复很多概念都是熟悉的。这也是为什么有些企业最终选的不是理论上“上限最高”的方案而是团队最能掌控的方案。毕竟数据库跑几年以后真正天天和它打交道的是运维和开发。不是选型 PPT。去年那两个项目为什么最后选了完全不同的数据库第一个项目是互联网业务。数据已经到了几 TB事务量还在继续涨而且明确要求后面可以水平扩容。这种情况下如果继续押在单机上未来迟早还要解决扩展问题。所以最后用了 OceanBase。主要原因很简单它需要的是未来的数据规模上限。第二个是制造企业 ERP。数据规模不到 1TB并发也不是特别夸张。最大的诉求反而是原来的业务尽量少改。迁移周期不能太长。现有 DBA 能继续维护。这种场景如果为了“分布式”本身增加一大堆复杂度收益其实不明显。最后用了 KingbaseES 的集中式/高可用方案。上线以后业务跑得也比较稳定。所以这两个项目放在一起看我反而觉得挺典型。不是OceanBase 和金仓谁赢了而是两个项目分别选到了比较适合自己的数据库。如果现在让我重新做一次选型我会先问这几个问题不会先问数据库排行榜。而是先把业务拆开。数据量现在多大500GB 和 50TB 是完全不同的架构问题。三年以后预计多大现在能跑不代表未来能跑。如果数据每年翻倍那扩展能力的权重就得提高。并发到底有多少不要只看 DAU。数据库真正关心的是QPS TPS 峰值并发 连接数 长事务查询类型是什么系统里面到底是主键点查多还是多表JOIN GROUP BY 窗口函数 复杂报表这对数据库选型影响很大。有没有大量跨表事务分布式事务和本地事务的成本不是一回事。团队会不会维护这一点很多公司最后才想起来。其实应该一开始就问。最后说说我的看法如果系统已经到了单机无法舒服支撑的规模需要水平扩展、多副本、高并发甚至多地域部署OceanBase 这种原生分布式数据库非常值得考虑。它解决的是一个很明确的问题数据和业务继续增长以后数据库怎么往外扩。如果是传统 ERP、政企应用、核心业务系统数据规模并没有大到必须拆成分布式同时又比较在意原有数据库兼容、迁移成本和运维复杂度那么集中式 KingbaseES 往往是另一种比较现实的选择。尤其复杂查询比较多的时候不需要跨节点这件事本身就是一种优势。但这并不意味着集中式数据库复杂查询一定比分布式快。更准确的说法应该是数据规模还没有大到需要分布式的时候集中式架构少了一层分布式协调成本数据规模真正上来以后分布式架构可以用多节点计算能力换取更高的容量和吞吐上限。两边其实是在解决不同阶段的问题。所以如果现在有人问我OceanBase 和金仓到底选哪个我大概率不会马上给答案。我会先让他拿几条生产环境里最重的 SQL 出来。再看看真实数据量、并发、索引、事务模型和未来三年的增长预期。然后搭两套环境跑一遍。因为数据库这种东西官网参数可以看TPC 测试也可以参考。但最终真正给用户服务的还是你自己那几百张表、那几十条核心 SQL。数据库选型最靠谱的跑分永远是你自己的业务。
返回列表