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

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

去年碰巧接触了两个数据库选型项目。

一个最后选了 OceanBase,另一个用了金仓 KingbaseES。

两个项目差别其实挺大。前者数据规模已经到了几 TB,业务并发高,而且后面还要继续扩容;后者是比较典型的企业 ERP,数据量不到 1TB,更关注迁移成本、SQL 兼容和日常运维。

有意思的是,两个项目上线以后,客户反馈都不错。

这件事后来让我对数据库选型这件事有了一个更明确的看法:

数据库很难简单地分成"谁比谁强",更多时候是在看你的业务更适合哪种架构。

OceanBase 原生就是冲着分布式去的,节点越多,扩展空间越大。

KingbaseES 则更接近传统企业熟悉的关系型数据库使用方式,集中式、主备、高可用这些场景比较自然。如果当前业务量还没大到必须拆到多节点,集中式架构反而可能更简单。

这篇不准备单纯比跑分,主要聊一个更实际的问题:

为什么同样一条 SQL,到了集中式和分布式数据库里,执行方式会完全不一样?


先把一个问题说清楚:分布式并不等于"每条 SQL 都更快"

很多人第一次接触分布式数据库,容易形成一个直觉:

三台机器肯定比一台机器快。

但数据库不是这么算的。

如果任务本身可以很好地拆开,比如大表扫描、分区聚合、海量数据并行计算,多节点确实可以一起干活。

但如果是一条跨表很多、关联关系复杂的 SQL,事情就不一样了。

假设有三台节点。

订单表的一部分在节点 A,客户表在节点 B,商品信息又在节点 C。

这时候执行一条 JOIN,不只是 CPU 做计算,还可能出现:

text 复制代码
定位数据
→ 节点间传输
→ 数据重新分布
→ 局部计算
→ 汇总结果
→ 返回客户端

这里任何一个环节都会有成本。

而集中式数据库里,数据主要在一个实例内部完成读取、过滤、排序和 JOIN。

少了跨节点通信以后,很多中小规模查询反而更直接。

所以两种架构真正的区别不是:

text 复制代码
分布式 = 快
集中式 = 慢

而更像:

text 复制代码
分布式:拿额外的协调成本换扩展能力
集中式:拿规模上限换更简单的执行路径

这两个选择本身都没有问题。

关键看你的系统到底需要什么。


OceanBase 为什么更适合"大规模"

OceanBase 从架构设计上就是分布式数据库。

每个节点都有自己的计算、内存和存储资源,数据按照一定规则分布到不同节点,同时通过副本机制保证可靠性。

它最大的价值其实不是"某一条 SELECT 比别人快多少"。

而是:

当一台机器撑不住的时候,还可以继续往外扩。

例如一个电商系统,早期每天几百万订单,后面涨到几千万甚至更高。

集中式数据库可能需要不断升级 CPU、内存和存储。

硬件规模到一定程度以后,继续纵向升级会越来越贵。

分布式数据库则可以通过增加节点,把数据和计算继续拆出去。

这也是 OceanBase 比较擅长的地方。

对于互联网业务来说,这个能力很重要。

因为很多时候,你解决的不是:

现在这一条 SQL 能不能再快 50ms?

而是:

三年以后数据翻十倍,这套数据库还能不能继续扛?

从这个角度来看,OceanBase 的价值很清楚。


金仓更像传统企业数据库的"熟悉路线"

另一个项目使用的是 KingbaseES。

这个项目本身没有特别夸张的数据规模。

大约几百 GB 数据,日常业务以 ERP、报表、订单和后台管理为主,并发量也没有到互联网平台那种级别。

这种系统真正关心的东西反而比较传统:

SQL 能不能直接迁?

存储过程要改多少?

原来的 DBA 能不能维护?

主备怎么切换?

出了问题怎么恢复?

这时候集中式数据库的优势就出来了。

业务请求进入数据库以后,大部分操作都发生在本地实例内部。

查询、JOIN、排序、聚合,不需要为了"分布式"额外跨节点。

对于几百 GB 到 TB 级的数据,只要硬件合理、索引设计正常,很多企业系统根本没必要把查询拆到多节点。

这也是为什么我们那个 ERP 项目最终没有为了"架构先进"强行上分布式。

技术方案不是越复杂越好。

能够用两台机器解决的问题,没必要为了架构图好看上六台。


真正能看出差别的是复杂 JOIN

简单主键查询其实没太多可比性。

例如:

sql 复制代码
SELECT *
FROM orders
WHERE order_id = 10001;

索引正常的时候,主流数据库基本都不会太差。

真正容易把架构差异暴露出来的,是复杂查询。

例如下面这种:

sql 复制代码
SELECT
    o.order_id,
    o.customer_id,
    c.customer_name,
    p.product_name,
    oi.quantity,
    oi.price
FROM orders o
JOIN customers c
    ON o.customer_id = c.customer_id
JOIN order_items oi
    ON o.order_id = oi.order_id
JOIN products p
    ON oi.product_id = p.product_id
WHERE o.order_date >= '2026-01-01'
  AND o.status = 'completed'
ORDER BY o.order_date DESC
LIMIT 100;

这类 SQL 在 ERP、BI 和数据分析系统里很常见。

集中式数据库处理它的时候,优化器主要考虑:

  • 哪张表先过滤
  • JOIN 顺序怎么排
  • 走哪个索引
  • 用 Hash Join 还是 Nested Loop
  • 中间结果要不要排序
  • 是否需要并行执行

这些操作主要发生在单个数据库实例内部。

但如果换成分布式环境,还多了一个问题:

数据到底在哪台机器上?

假设:

text 复制代码
orders        → 节点 A、B、C
customers     → 节点 A、B、C
order_items   → 节点 A、B、C
products      → 节点 A、B、C

如果几张表的数据分布键正好和关联键一致,那很好。

数据可以本地 JOIN。

但如果不一致,就可能出现数据重分布。

例如订单按照 order_id 分区,客户按照 customer_id 分区。

做:

sql 复制代码
orders.customer_id = customers.customer_id

时,数据库可能需要把部分订单数据重新发到对应客户所在节点。

这就是分布式数据库经常提到的 Shuffle 或数据重分布。

一旦数据量大起来,网络就会参与整个执行过程。

所以分布式复杂查询的性能,不只是取决于 SQL 怎么写。

表怎么分区,同样重要。


一条 SQL 快不快,有时候在建表那天就已经决定了一半

这也是我后来做分布式数据库项目感触比较深的一点。

传统数据库里,开发人员最常考虑的是索引。

例如:

sql 复制代码
CREATE INDEX idx_orders_customer
ON orders(customer_id);

到了分布式数据库,还得多考虑一个问题:

text 复制代码
这张表到底按照什么字段分布?

如果分布键选对了,大量查询都可以在本地完成。

如果选错了,同一条业务链路可能不断跨节点。

举个例子。

一个订单系统最主要的查询方式是:

sql 复制代码
WHERE customer_id = ?

而且大量 JOIN 都是:

sql 复制代码
orders.customer_id = customer.customer_id

那按照 customer_id 去做数据分布通常比较自然。

但如果一开始按照其他字段拆,后面大量查询都可能发生跨节点访问。

所以分布式数据库有一个很现实的问题:

前期架构设计比集中式数据库更重要。

因为有些坑不是后来加一个索引就能完全补回来的。


嵌套子查询,也是优化器的一道考试题

再看一个实际系统很容易出现的 SQL:

sql 复制代码
SELECT
    order_id,
    customer_id,
    amount,

    (
        SELECT COUNT(*)
        FROM order_items oi
        WHERE oi.order_id = o.order_id
    ) AS item_count,

    (
        SELECT SUM(amount)
        FROM payments p
        WHERE p.order_id = o.order_id
    ) AS total_payment

FROM orders o
WHERE order_date >= '2026-01-01';

这种代码开发人员很爱写。

因为直观。

一眼就能看出来:

订单数量、商品数量、支付金额。

但数据库最怕"看起来直观,实际执行很贵"。

如果最外层查出了 10 万条订单,而里面的子查询每一行都重新跑一次,那代价就大了。

好的优化器会尝试把这类 SQL 改写。

比如把:

text 复制代码
相关子查询

改成:

text 复制代码
聚合
+
JOIN

让原来可能执行几万次的子查询,变成一次数据扫描。

集中式数据库做这种改写相对直观。

分布式数据库则还需要继续判断:

聚合放在哪个节点?

能不能下推?

结果在哪里汇总?

JOIN 会不会重新分布?

因此同一条 SQL,在两种架构下看到的执行计划可能差别很大。

这也是为什么我现在做数据库选型,基本不会只测试简单 CRUD。

复杂 SQL 才更容易看到数据库真正的能力。


窗口函数也是同样的道理

比如:

sql 复制代码
SELECT
    order_id,
    customer_id,
    amount,

    ROW_NUMBER() OVER (
        PARTITION BY customer_id
        ORDER BY order_date DESC
    ) AS rn,

    SUM(amount) OVER (
        PARTITION BY customer_id
        ORDER BY order_date
        ROWS BETWEEN UNBOUNDED PRECEDING
        AND CURRENT ROW
    ) AS running_total

FROM orders
WHERE order_date >= '2026-01-01';

这种 SQL 对数据库来说,本质上绕不开几个动作:

text 复制代码
过滤
→ 分区
→ 排序
→ 窗口计算

集中式环境下,这些数据如果能在单机内存和磁盘之间完成处理,路径比较清晰。

分布式环境如果恰好按照 customer_id 分布,问题也不大。

但如果数据分布方式和窗口函数的 PARTITION BY 对不上,就可能需要先重新分发数据,再进行计算。

所以还是回到那个问题:

分布式数据库不是复杂查询一定慢,而是复杂查询对数据分布更加敏感。

这句话比直接说"集中式复杂查询更快"要准确得多。


我后来已经不太喜欢直接比毫秒了

以前做数据库测试,我也喜欢整理成这种表:

数据库 查询耗时
A 600ms
B 800ms

看起来特别直观。

后来项目做多了,发现这种表如果没有上下文,其实意义不大。

因为至少要说明:

text 复制代码
CPU 是否相同
内存是否相同
磁盘是否相同
数据规模是否相同
并发数是多少
缓存是否预热
索引是否一致
统计信息是否准确
并行度是多少
数据如何分区
SQL 是否完全一样

任何一个变量改变,结果都可能翻过来。

甚至同一个数据库:

第一次:

text 复制代码
3.2 秒

第二次:

text 复制代码
400ms

都有可能。

因为第一次从磁盘读,第二次已经命中缓存。

所以现在我更愿意看:

text 复制代码
P50
P95
P99
吞吐量
CPU
IOPS
网络流量
执行计划

而不是只截一条 SQL 跑一次,然后宣布谁更快。


运维成本,其实比性能更容易被低估

两个项目做下来,我觉得数据库选型还有一个经常被忽视的问题:

谁来维护?

OceanBase 的分布式架构优势很明显,但相应地,需要理解的东西也更多。

例如:

text 复制代码
节点
Zone
副本
Leader
分区
数据分布
租户
资源隔离
跨节点事务

如果团队本身就有比较成熟的数据库平台团队,这些问题不算什么。

但如果公司只有一两个 DBA,还同时维护 Oracle、MySQL、Redis、Kafka,再上一套分布式数据库,学习和运维成本就得认真算进去。

集中式数据库通常更符合传统 DBA 的经验模型。

例如:

text 复制代码
主库
备库
WAL/日志
流复制
连接池
索引
SQL优化
备份恢复

很多概念都是熟悉的。

这也是为什么有些企业最终选的不是理论上"上限最高"的方案,而是团队最能掌控的方案。

毕竟数据库跑几年以后,真正天天和它打交道的是运维和开发。

不是选型 PPT。


去年那两个项目,为什么最后选了完全不同的数据库

第一个项目是互联网业务。

数据已经到了几 TB,事务量还在继续涨,而且明确要求后面可以水平扩容。

这种情况下,如果继续押在单机上,未来迟早还要解决扩展问题。

所以最后用了 OceanBase。

主要原因很简单:

它需要的是未来的数据规模上限。

第二个是制造企业 ERP。

数据规模不到 1TB,并发也不是特别夸张。

最大的诉求反而是:

原来的业务尽量少改。

迁移周期不能太长。

现有 DBA 能继续维护。

这种场景如果为了"分布式"本身增加一大堆复杂度,收益其实不明显。

最后用了 KingbaseES 的集中式/高可用方案。

上线以后业务跑得也比较稳定。

所以这两个项目放在一起看,我反而觉得挺典型。

不是:

OceanBase 和金仓谁赢了?

而是:

两个项目分别选到了比较适合自己的数据库。


如果现在让我重新做一次选型,我会先问这几个问题

不会先问数据库排行榜。

而是先把业务拆开。

数据量现在多大?

500GB 和 50TB 是完全不同的架构问题。

三年以后预计多大?

现在能跑不代表未来能跑。

如果数据每年翻倍,那扩展能力的权重就得提高。

并发到底有多少?

不要只看 DAU。

数据库真正关心的是:

text 复制代码
QPS
TPS
峰值并发
连接数
长事务

查询类型是什么?

系统里面到底是:

text 复制代码
主键点查多

还是:

text 复制代码
多表JOIN
GROUP BY
窗口函数
复杂报表

这对数据库选型影响很大。

有没有大量跨表事务?

分布式事务和本地事务的成本不是一回事。

团队会不会维护?

这一点很多公司最后才想起来。

其实应该一开始就问。


最后说说我的看法

如果系统已经到了单机无法舒服支撑的规模,需要水平扩展、多副本、高并发甚至多地域部署,OceanBase 这种原生分布式数据库非常值得考虑。

它解决的是一个很明确的问题:

数据和业务继续增长以后,数据库怎么往外扩。

如果是传统 ERP、政企应用、核心业务系统,数据规模并没有大到必须拆成分布式,同时又比较在意原有数据库兼容、迁移成本和运维复杂度,那么集中式 KingbaseES 往往是另一种比较现实的选择。

尤其复杂查询比较多的时候,不需要跨节点这件事本身就是一种优势。

但这并不意味着:

集中式数据库复杂查询一定比分布式快。

更准确的说法应该是:

数据规模还没有大到需要分布式的时候,集中式架构少了一层分布式协调成本;数据规模真正上来以后,分布式架构可以用多节点计算能力换取更高的容量和吞吐上限。

两边其实是在解决不同阶段的问题。

所以如果现在有人问我:

OceanBase 和金仓到底选哪个?

我大概率不会马上给答案。

我会先让他拿几条生产环境里最重的 SQL 出来。

再看看真实数据量、并发、索引、事务模型和未来三年的增长预期。

然后搭两套环境跑一遍。

因为数据库这种东西,官网参数可以看,TPC 测试也可以参考。

但最终真正给用户服务的,还是你自己那几百张表、那几十条核心 SQL。

数据库选型最靠谱的跑分,永远是你自己的业务。

相关推荐
Bug修理工Bubble1 小时前
Swift ARC:一个对象到底什么时候才会被释放?
前端
cjz38991 小时前
Redis + Lua 实现秒杀优惠券 IP + 用户双维度令牌桶限流
后端
ClouGence1 小时前
GPT-6 做 UI 自动化测试:Demo 惊艳,但真的适合长期回归吗?
前端·chatgpt·测试
Shinomiya1 小时前
虚拟地址空间:从“地址一样但物理内存不同”说起
后端
海宇数据1 小时前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化残值评估网关
人工智能·python·架构·自动化
孙启超1 小时前
【AI开发之Rust】第 1 课:认识 Rust 与开发环境 —— 装好工具链,跑通第一个程序
开发语言·人工智能·后端·ai·rust·安全架构
Erishen1 小时前
从 SQLite 到 LLM 重排:一个 Rust RAG 服务的七层设计决策
架构·开源·agent
阿酷tony1 小时前
视频专栏列表的防录屏水印和跑马灯效果(也可网站调用)
java·前端·音视频
yindeshuiketang2 小时前
企业FDE架构方法论到实战指南从想法到商业变现:需求·设计·技术·测试·运维·交付·变现-小红书&抖音 AI马教授 职场启航宝
运维·人工智能·架构