KingbaseES与OceanBase性能对比:单机架构如何赢得SQL执行效率
2026/9/18 18:04:24 网站建设 项目流程

大家做国产数据库选型或者替代方案评审的时候,我最常被问到的一个问题不是“哪个功能更强”,而是“同样一条 SQL,为什么在 OceanBase 上和 KingbaseES 上跑出来的效果完全不是一个体感”。更直接一点的问法是:金仓 KingbaseES 既不搞分布式存储,也不搞 Paxos 多副本,它凭什么跟 OceanBase 这种明星级产品放在一起比性能?

这个问题其实问到了根子上。很多人以为“性能”是跑分跑出来的,是 CPU 频率和磁盘 IOPS 堆出来的,但实际上对一个数据库来说,性能的底层逻辑是架构。一条 SQL 从客户端发出去,到返回结果集,中间走的是完全不同的两条路:OceanBase 走的是一条为分布式一致性而设计的“协调之路”,KingbaseES 走的是一条把单机硬件压榨到极致的“本地之路”。这两条路没有绝对的优劣,但它们决定了你在什么场景下会感觉到快,在什么场景下会感觉到慢。

这篇文章我想把这两条路掰开揉碎讲清楚,重点放在 KingbaseES 的性能竞争力到底从哪里来。不吹不黑,只说架构逻辑和实际排障时的体感。

1. 为什么 OceanBase 和 KingbaseES 总被放在一起比:目标同向,路线反向

1.1 表面上的共同点:都在做同一件事

先说结论:OceanBase 和 KingbaseES 本质上面对的是同一个市场——关键行业的核心系统数据库替代。金融、运营商、政务、能源,这些行业的客户有一个共同特点:数据量大、并发高、对一致性要求极其苛刻,同时又有很强的国产化替代诉求。

在这个背景下,两家产品经常出现在同一个招标项目的候选名单里,其实是很自然的事。但如果你只看产品宣传页,你会觉得它们什么都像:都支持 SQL,都支持事务,都兼容 Oracle 或 MySQL 的某种语法,都宣称自己在 TPC-C、TPC-H 这类测试里成绩不错。

可一旦把真实的业务 SQL 丢进去跑,差别立刻显现。这个差别不藏在功能列表里,而是藏在架构选择里。

1.2 OceanBase 的路线:原生分布式,先解决“怎么扩展”

OceanBase 从诞生第一天起就是按分布式架构设计的。它的核心思路是:把一份数据分成多个分片,分散到多台服务器上,每台服务器只存一部分数据,然后通过 Paxos 协议保证多副本之间的一致性。

这个架构带来的最大好处是水平扩展能力——业务量涨了,加机器就行,不需要停业务,不需要拆库拆表。但代价也很明显:一条 SQL 一旦涉及跨节点数据,就必须走分布式执行计划,把数据在节点之间搬来搬去。搬数据的过程在数据库内部叫数据重分布(shuffle),这是分布式数据库性能开销的大头。

用一句话概括:OceanBase 的性能竞争力主要来自“用多台机器的资源干一台机器的活”,它的核心复杂度集中在“怎么让一堆机器像一台机器一样工作”。

1.3 KingbaseES 的路线:单机内核深度优化,先解决“单条 SQL 有多快”

KingbaseES 走的是另一个方向。它是基于 PostgreSQL 内核演进的产品,保留了 PostgreSQL 强大的优化器和执行引擎,同时针对国内企业级场景做了大量改造。在默认部署形态下,它是单机架构,主备通过复制同步,数据不需要分片,SQL 不需要跨节点协调。

这意味着一条 SQL 的整个执行过程,从解析、优化到执行,全部发生在一台机器的内存和磁盘之间,没有网络往返,没有协调节点,没有数据重分布。

它的性能竞争力来自两个层面:一是 PostgreSQL 内核本身在单机性能优化上几十年的积累;二是金仓针对国产芯片、国产操作系统做了深度适配,在飞腾、鲲鹏、海光这些平台上能把硬件性能吃得更透。

对比维度OceanBaseKingbaseES
核心架构原生分布式、存储计算分离单机集中式、主备复制
数据分片自动分片、多副本不分片,依赖硬件纵向扩展
一致性实现Paxos 多副本协议主备同步/异步复制
SQL 执行方式分布式执行计划,可能跨节点重分布数据本地执行计划,单机完成
扩展方式加节点横向扩展升级硬件或读写分离
性能优化重点分布式协调、网络开销、负载均衡优化器、缓存、磁盘 IO、并行查询

看到这张表你应该明白了:这两家不是谁比谁强的竞争关系,而是选择了完全不同的技术路线。搞清楚这一点,再去讨论“一条 SQL 谁跑得快”才有意义。

2. 一条 SQL 在两条路上的执行路径:从解析到返回结果集的分岔点

我们选一条业务里非常典型的 SQL,走一遍它在两个数据库内部的完整旅程:

SELECT c.cust_name, SUM(o.amount) AS total_amount FROM orders o JOIN customers c ON o.cust_id = c.id WHERE o.create_time >= '2024-01-01' AND o.status = 'PAID' GROUP BY c.cust_name ORDER BY total_amount DESC LIMIT 10;

这条 SQL 涉及 JOIN、过滤、分组聚合、排序、分页,算是 OLAP 场景里常见的基本款。两条路线在这条 SQL 上的差异,几乎覆盖了所有关键分岔点。

2.1 分岔点一:语法解析和合法性校验的清单不同

任何数据库收到 SQL 之后,第一步都是语法解析,把文本变成内部语法树。这一步的性能差异其实不大,真正的差异在于“能解析什么”。

OceanBase 在语法兼容上主打 MySQL 和 Oracle 两个模式。KingbaseES 的看家本领是 Oracle 兼容,同时兼容 PostgreSQL 和 MySQL 的常用语法。

这里有一个容易被低估的点:兼容性直接决定了一条 SQL 能不能用最简单的写法跑出最好的计划。举个例子,很多从 Oracle 迁移过来的业务会用CONNECT BY做层次查询,用MERGE INTO做增量更新。如果目标数据库不支持这些语法,你就得改 SQL——而改写之后的 SQL 往往不是性能最优的形态。KingbaseES 在 Oracle 兼容上做得比较深,很多迁移项目里 SQL 可以不做修改直接跑,这一步就省掉了大量改写导致的性能损耗风险。

从我的实际经验来看,在国产数据库迁移项目中,“语法能不能过”只是第一关,“改写后的 SQL 性能会不会劣化”才是第二关,而第二关往往更致命。所以兼容性这个东西,表面上是语法问题,实际上深度影响性能。

2.2 分岔点二:优化器生成执行计划的输入完全不一样

语法解析之后是重头戏——查询优化。优化器的作用是决定“怎么查最快”,它通常基于代价估算(CBO),给每种可能的执行方式算一个预期代价,然后选代价最小的。

OceanBase 的优化器要额外考虑一件事:数据在哪个节点上。如果一张表被分片到了 20 台服务器,那么 JOIN、GROUP BY 这些操作天然就是分布式的。优化器不仅要决定用不用索引、用哪种 JOIN 方式,还要决定数据怎么在节点之间流转——是广播小表,还是重分布大表。这些决策直接决定了 SQL 的网络开销,而网络开销往往比磁盘 IO 更慢、更不可控。

KingbaseES 的优化器不需要考虑跨节点问题。它只需要专注于一件事:选择最优的本地执行路径——走哪个索引、用哪种 JOIN 算法(嵌套循环、哈希连接、归并连接)、是否启用并行、以什么顺序扫描表。

你可能会觉得 KingbaseES 的优化器工作更简单,但“简单”恰恰是优势。一条 SQL 在单机上可能只有几十种执行计划组合,在分布式环境里可能生成上千种——计划空间越大,优化器选到次优计划(甚至坏计划)的概率就越大。单机优化器虽然选择空间小,但每一种选择都是围绕真实代价计算的,稳定性反而更高。

2.3 分岔点三:执行引擎的“搬数据”和“本地算”之争

这是两条路差异最悬殊的地方。

在 OceanBase 上,刚才那条 SQL 如果 orders 表和 customers 表的连接键不在同一个分片键上,执行引擎就必须把两边的数据按连接键值重新打散到所有节点,然后每个节点只算自己那一份,最后汇总。这个“打散—重算—汇总”的流程,每一步都涉及网络传输和节点间同步。数据量小的时候没感觉,数据量上到千万行、亿行,时间几乎全花在搬数据上。

在 KingbaseES 上,整个过程没有一次网络传输:扫描、连接、分组、排序全部在一台机器的内存里完成,最多是多个 CPU 核并行处理不同数据块。

用大白话说:OceanBase 是“叫了一堆人过来一起干活,但每一道工序之间都要交接”;KingbaseES 是“一个全能师傅从头干到尾,中间的半成品不用搬来搬去”。对很多中型规模的数据集来说,后者反而更快。

2.4 分岔点四:执行计划缓存和作用域

两个数据库都会缓存执行计划,避免每次执行 SQL 都重新做优化。但缓存的粒度不一样。

OceanBase 的执行计划缓存要考虑分布式环境下的路由信息、分区信息。如果一张分区表的统计信息发生变化,或者某个节点不可用,执行计划可能需要重新生成。在复杂分布式集群里,执行计划失效是很常见的,而重新生成计划的代价比单机高得多。

KingbaseES 的缓存在这一点上非常省心:它基于 SQL 文本做计划缓存,同样的 SQL 只要参数不同,直接走通用计划。虽然偶尔会遇到“通用计划不如定制计划”的经典问题,但整体上对 OLTP 这类以短查询为主的业务非常友好——短查询的执行时间本来就只有毫秒级,省掉优化时间就是实实在在的收益。

我见过不少团队在用分布式数据库跑 OLTP 业务时遇到一个问题:单条 SQL 的并发量很高,每条 SQL 又要花不少时间在计划生成和分布式协调上,导致 CPU 大量消耗在“执行之前的事情”上,而不是真正的数据计算上。而 KingbaseES 这类单机数据库,同样一批短 SQL,CPU 几乎全部花在有效的索引查找和数据返回上。

3. KingbaseES 性能竞争力藏在哪几个关键环节:不只是“PG 套壳”这么简单

很多人一听 KingbaseES 基于 PostgreSQL,就下意识觉得“这不就是改了个名吗”。实际用过就会发现这种判断太粗糙了。金仓确实借了 PG 的底子,但它在性能上的功夫,更多是在 PG 内核的基础上做了针对性的深挖和改造。

3.1 共享缓冲区与本地内存利用:OLTP 短查询的隐形加速器

数据库 90% 以上的性能问题,最后都能归结到内存和磁盘的博弈上。KingbaseES 继承了 PostgreSQL 的共享缓冲区(shared_buffers)机制,同时结合国产服务器的实际内存配置做了调优。

这里面最值得说的是:单机架构让内存命中率可以做到非常稳定。所有热点数据都在这台机器的内存里,不存在“数据在远端节点上要多一次网络读取”的问题。对高并发的订单查询、账户余额查询、流水查询这类业务,只要内存够大,缓存命中率可以长期维持在 95% 以上,查询时间基本就是内存读的速度。

很多从 Oracle 迁移到国产库的团队,最不适应的就是“怎么还要关心 shared_buffers 配多大”。这个参数确实需要调,但调好之后的收益非常直接。根据金仓官方文档的建议,shared_buffers 一般设置为物理内存的 25% 左右,再配合操作系统层面的 page cache,实际可用缓存往往能覆盖整张热表。

对比 OceanBase 的架构:它的存储引擎用 LSM-Tree,写入路径经过内存的 memtable,读的时候要先查内存再查磁盘,同时还要走多副本的一致性协议。写入吞吐确实强,但读路径上的环节比单机数据库多,这是分布式架构无法回避的额外开销。

3.2 存储引擎和索引设计:经典路线的稳定红利

KingbaseES 的存储引擎是堆表 + MVCC,索引默认是 B-tree,同时支持 Hash、GiST、SP-GiST、GIN、BRIN 等多种索引类型。这套组合在 PostgreSQL 社区里被验证了二十多年,属于数据库领域的“经典款”——不花哨,但该有的都有了。

对实际业务来说,索引带来的性能提升往往比存储引擎本身的差异更直接。比如:

  • 一个等值查询,走 Hash 索引可能比走 B-tree 更快;
  • 一个范围查询,B-tree 是最合适的选择;
  • 全文检索或者数组包含这类场景,GIN 索引优势明显;
  • 数据量极大但数据的物理顺序与查询条件高度相关的场景,BRIN 索引能以极小的空间代价提供不错的过滤能力。

OceanBase 的存储引擎是 LSM-Tree,它在高并发写入场景下非常能打,但 LSM-Tree 的代价是读放大和空间放大。虽然 OceanBase 做了很多优化(比如分层压缩、bloom filter),但“写优化”和“读优化”之间的跷跷板效应是逃不掉的。

如果你业务里读多写少(绝大多数传统业务都是这个形态),KingbaseES 的经典存储引擎在稳定性和可预测性上更有优势。

3.3 并行查询能力:单机内部的多核利用

很多人有个误区:以为单机数据库只能用一个 CPU 核跑 SQL。KingbaseES 的并行查询机制其实可以调动多个核同时处理一条 SQL。

它的执行模型是:优化器预估 SQL 的代价,超过阈值就启用并行。以刚才那条 GROUP BY 聚合查询为例,KingbaseES 可以这样并行:

  1. 多个并行 worker 同时扫描 orders 表,各自负责不同的数据块;
  2. 每个 worker 把符合条件的数据做本地预聚合(partial aggregation);
  3. 第一步聚合结果提交给 leader 进程,leader 做最终聚合(final aggregation)。

整个过程还是在同一台机器内部,但通过并行把 CPU 多核能力用起来了。对分析型 SQL 来说,并行度配置合理的情况下,性能可以提升数倍。

OceanBase 同样有并行查询能力,但它的并行发生在多台机器之间。并行度更高,但并行任务的调度、数据交换的开销也更大。如果集群规模不够大,或者网络带宽成为瓶颈,分布式的并行不一定比单机并行快。

这里有一个非常实用的工程经验:不要盲目追求高并行度。在 KingbaseES 上,max_parallel_workers_per_gather设置成 2 到 4 往往就能覆盖绝大多数场景,并行度太高反而会因为进程间通信和上下文切换带来额外开销。做压测时,应该从低到高一档一档试,找到拐点。

3.4 Oracle 兼容带来的“迁移后性能不倒退”红利

最后这一点可能是 KingbaseES 在国产数据库阵营里最独特的竞争力——它对 Oracle 的兼容不是停留在语法层面,而是深入到了行为层面。

这个“行为兼容”会直接体现在性能上。举个经典例子:Oracle 里的ROWNUM分页写法,很多国产数据库只支持改写后的LIMIT/OFFSET写法,但改写的执行计划不一定最优。KingbaseES 支持ROWNUM,并且能把它优化成“取到 N 行即停止”的短路执行——比如只取前 10 行,就不会傻傻地把所有符合条件的数据都算完再截断。

再比如NULL语义、字符串拼接规则、隐式类型转换的行为,这些细枝末节的东西如果不兼容,SQL 改写时就会改变原意,最终导致执行计划和性能不可控。KingbaseES 在这些细节上做了大量对齐,让老 Oracle 系统的 SQL 能原封不动地跑出和原来同级别的性能。

从项目实际来看,迁移后性能倒退 80% 的案例,绝大多数不是因为数据库本身慢,而是因为 SQL 被改写后执行计划劣化了。金仓的兼容策略从源头堵住了这个问题。

4. 三个高频场景实测:同样的 SQL,两条路线的表现逻辑

前面讲了架构和原理,这一节用三个具体的场景,带大家看看到底怎么判断一条 SQL 在两条路上会表现出什么差异,以及排障时应该从哪里下手。

4.1 场景一:GROUP BY + JOIN 大查询(慢 SQL 优化的经典题)

业务场景很常见:有个大订单表(几千万行),要按客户维度汇总消费金额。这是慢 SQL 优化里最经典的重度聚合场景。

在 OceanBase 上执行时,如果订单表和客户表的分布键不一致,优化器会生成重分布计划:先把订单表按 cust_id 哈希分发到所有节点,再把客户表按 id 哈希分发。两个表重分布完成之后,每个节点才本地做 JOIN 和 GROUP BY。

在 KingbaseES 上执行时,优化器有两种选择:如果客户表足够小,选择 Hash Join 时会把客户表作为驱动表加载到内存,然后全表扫描订单表,在内存里做连接和聚合;如果两个表都很大,可以启用并行查询,多个 worker 分别扫描订单表的不同部分,本地聚合后汇总。

两条路线的共同点是:聚合的计算量都被分散了。区别在于,OceanBase 分散到机器之间,KingbaseES 分散到 CPU 核之间。网络带宽是 GB 级别,内存带宽是几十 GB 到上百 GB 级别,差了一个数量级。所以对数据量在单机能装下的场景,KingbaseES 的优势非常明显。

这里给一个排查慢 SQL 的实际建议:在 KingbaseES 里用EXPLAIN ANALYZE看执行计划时,重点关注三点——有没有走索引、Hash Join 时哈希表有没有落盘、并行 worker 的实际启动数量是不是和配置一致。这三个点基本覆盖了 80% 的重度聚合查询性能问题。

4.2 场景二:窗口函数 + 排序(ROW_NUMBER 去重取最新)

现在业务里大量用到窗口函数,典型场景是“取每个用户最近一笔订单”。

SELECT * FROM ( SELECT o.*, ROW_NUMBER() OVER (PARTITION BY cust_id ORDER BY create_time DESC) AS rn FROM orders o WHERE o.status = 'PAID' ) t WHERE rn = 1;

窗口函数的核心成本在排序。PARTITION BY cust_id ORDER BY create_time DESC意味着要按客户 ID 分组、组内按时间排序。

在分布式架构里,窗口函数的分区键和表的分片键如果不一致,优化器就必须把数据按分区键重新打散到各节点,然后在每个节点上做组内排序。数据重分布的代价在这里会被指数级放大——重分布的时间甚至可能超过排序本身。

在 KingbaseES 上,如果 orders 表在 cust_id 上有索引,优化器可以利用索引的有序性避免物理排序。即使没有索引,单机上做一次全表排序的开销也远小于分布式环境下的“重分布 + 多次排序”。再加上 PostgreSQL 对窗口函数有专门的优化——通过top-N堆排序(heapsort)或者incremental sort避免全量排序——在“只取每组前 N 行”的场景下,实际排序代价比想象中小得多。

这个场景也顺便回应了搜索热词里“sql窗口函数”“sql语句去重”的关注点:去重取最新的本质就是一个分组排序的过程,判断数据库行不行,就看它在分组排序上有没有省力的执行策略。

4.3 场景三:大批量数据导入和去重

最后一个场景其实最能区分架构差异。假设你要一次性往数据库里灌 500 万行订单数据,同时要求数据不能重复(ON CONFLICT DO UPDATEMERGE INTO语义)。

OceanBase 的 LSM-Tree 存储引擎在这个场景下优势明显:写入先进内存 memtable,批量转储到磁盘,顺序写为主,写放大被控制得比较好。高吞吐导入对分布式数据库来说确实是主场。

KingbaseES 的堆表 + B-tree 在导入时则要面对经典的 B-tree 维护开销:每插入一行都要更新索引,如果索引频繁分裂,还会产生额外写放大。这也是很多人诟病 PG 系数据库“写入慢”的根源。

但这里有一个实践中的反转:单机写入慢,可以通过批量提交和并行导入来弥补。把 500 万行的 INSERT 拆成多个并发任务,每个任务按主键范围分成片段批量插入,同时在导入期间去掉非必要的二级索引(导入后再建),KingbaseES 的实际导入性能完全可以压到业务可接受的范围内。而且导入完成后,数据不需要跨节点再平衡——在 OceanBase 里导入完成后经常还需要做一次数据均衡和 compaction,这又是一个隐性时间成本。

核心思路是:在选型阶段就要明确你的业务是“写一次读一万次”还是“时刻高频写”。如果是前者,KingbaseES 这种单机架构完全扛得住,而且运维简单得多。

5. 选型不是站队:什么业务适合走哪条路

看了这么多对比,如果你问我“OceanBase 和金仓到底选哪个”,我的答案永远是:先回答你自己的业务是什么形态。

拿一张表帮你快速定位:

你的业务特征更适合的路线原因
数据量单机装得下(几 TB 以内),但并发很高KingbaseES单机避免分布式协调开销,短查询快,运维简单
数据量持续增长,明确超过单机容量上限OceanBase分布式架构天然支持横向扩展
业务 SQL 以 JOIN、聚合、复杂分析为主KingbaseES单机本地执行,无跨节点重分布成本和网络开销
业务要求极高的写入吞吐(如流水类数据)OceanBaseLSM-Tree 的写路径更强
老 Oracle 系统迁移,希望 SQL 少改甚至不改KingbaseESOracle 兼容深度高,性能不易劣化
对跨机房容灾、多活有强诉求OceanBase原生多副本 + Paxos,容灾能力内置
团队 DBA 数量少,希望运维尽量简单KingbaseES单机架构排查问题链路短,不需要学分布式运维
未来几年数据规模有明确的几何级增长预期OceanBase避免以后拆库拆表的痛苦

这个表格不是绝对的,但方向是对的。

另外还要说一个很多人踩过的坑:迁移评估时只看语法兼容,不看执行计划形态。两个数据库都能执行同一条 SQL,不代表执行方式一样。在 Oracle 上走了索引的查询,迁移到另一个库之后,可能因为统计信息、优化器版本、数据分布不同,变成了全表扫描。

所以我的建议是:无论你倾向选哪家,正式立项前先做一轮“真实业务 SQL 全量跑批”——拿生产环境里最重的那 20 到 30 条 SQL,在新库上用真实数据量跑一遍,对比执行计划和响应时间。这一步省不掉,也偷不得懒,它才是选型最有价值的参考依据。

6. 写在最后:抛开“谁更强”,看“谁更合适”

回到标题那个问题:KingbaseES 的性能竞争力从哪来?我的答案是:从“专注”中来。它专注做单机内核的深度优化,专注把 Oracle 兼容做到位,专注让数据库在国产硬件栈上跑得更稳。它没有去追分布式这个热点,而是把一条更传统的路走到了极致。而 OceanBase 的竞争力在于“重构”——用分布式架构重新定义了 SQL 在多机环境下的执行方式。

这两条路没有谁一定优于谁。真实世界里,一个小型系统用 OceanBase 可能根本感受不到分布式的红利,反而被它的复杂度拖累;而一个超大规模系统硬要用 KingbaseES 撑,也很可能卡在单机容量的天花板上。技术选型最忌讳的就是“因为谁名气大就选谁”,更忌讳的是“因为谁便宜就选谁”。

我个人在实际项目中的体感是:大多数企业的核心业务系统,数据量远没到单机装不下的程度,真正让他们痛苦的不是架构不够先进,而是运维太复杂、SQL 跑太慢、出了问题没人能排查。对这类用户来说,KingbaseES 这种“经典单机 + 深度兼容”的路线反而是风险更低的选择。当然,如果你正在设计一个从零开始的、有明确海量数据预期的互联网级系统,OceanBase 的分布式能力就是需要考虑的。

最后再分享一个实用技巧:选型测试的时候,不要只盯着平均响应时间,要看P99 延迟和延迟抖动。分布式数据库在平均表现上往往不差,但在系统负载波动、节点间网络抖动、数据重分布任务并发执行时,P99 延迟会突然变得很难看。单机数据库在这个指标上天然更稳定。而核心交易系统的用户感知,恰恰是由那 1% 的最慢请求决定的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询