ARTICLE DETAIL

资讯详情

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

KingbaseES与OceanBase性能对比:单机架构如何赢得SQL执行效率

KingbaseES与OceanBase性能对比:单机架构如何赢得SQL执行效率 大家做国产数据库选型或者替代方案评审的时候我最常被问到的一个问题不是“哪个功能更强”而是“同样一条 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 这类单机数据库同样一批短 SQLCPU 几乎全部花在有效的索引查找和数据返回上。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 可以这样并行多个并行 worker 同时扫描 orders 表各自负责不同的数据块每个 worker 把符合条件的数据做本地预聚合partial aggregation第一步聚合结果提交给 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 UPDATE或MERGE 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% 的最慢请求决定的。
返回列表