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。
数据库选型最靠谱的跑分,永远是你自己的业务。