本人从2021年至今(2025年12月)参与过几十个去O项目,对常见的国产数据库
达梦,金仓,OB,TDSQL,GoldenDB,GaussDB,openGauss等均有深入了解
我可以很负责任的说,上面提到的国产数据库基础算子性能至今(2025年12月)还未赶上原生PG
有些数据库基础算子性能可以达到PG18的80-90%,有些数据库基础算子性能只有原生PG18的一半
而PG18基础算子性能又只有Oracle的一半(大多数场景,少数场景除外)
跑Oracle数据库,CPU一般配置INTEL志强2,3,4,5,6代,或者AMD EPYC
跑国产数据库,CPU要么是海光,要么ARM。最新的海光CPU比ARM性能要强一些,但是性能还未赶上INTEL志强2代(在笔者眼中,志强2代都属于垃圾CPU范畴了)
最新的海光CPU单线程性能只有AMD EYPC ZEN5的一半,明年(2026年),AMD要发布zen6了,性能又有很大提升,CPU性能差距只会越来越大
如果Oracle是跑在INTEL志强2代,3代,4代下(2,3,4代性能差距不大,挤牙膏,志强5代后提升明显),使用海光最新CPU替换,同样跑Oracle,性能大概会下降20-30%
如果Oracle是跑在INTEL志强6代,AMD EYPC ZEN5下,使用海光最新CPU替换,同样跑Oracle性能直接下降一半
如果Oracle是跑在INTEL志强2代,3代,4代下(2,3,4代性能差距不大,挤牙膏,志强5代后提升明显),使用海光最新CPU替换,跑原生PG,性能大概只有Oracle的40%
如果Oracle是跑在INTEL志强6代,AMD EYPC ZEN5下,使用海光最新CPU替换,跑原生PG,性能大概只有Oracle的20-25%
从Oracle迁移至国产数据库,想要性能不下降,用户使用体验不变,只能期望之前的Oracle系统没做过深入优化
在国产数据库中,可以通过调整SQL执行计划,创建索引,对SQL进行等价改写等等一系列优化手段确保迁移至国产数据库后用户体验不变,甚至更好
如果SQL写法,执行计划已经是最优了,迁移至国产数据库,要想SQL跑得快只有2个办法,要么使用最新最强的服务器CPU,要么提升数据库基础算子性能
由于CPU先进制成限制(台积电无法给华为ARM服务器CPU代工),CPU架构限制(海光获得的是AMD ZEN1架构指令集永久授权,AMD 2026年发布zen6架构)
想从CPU这条路提升性能,短时间内不太可能,剩下就只有提升数据库基础算子性能这一条路了
本文不讨论国产数据库的高可用能力,不讨论对O兼容性,也不讨论稳定性,不讨论可观测性,不讨论易用性和可维护性
只讨论基础算子性能
科普一下,什么是基础算子?我理解的基础算子如下:
全表扫描
索引快速全扫描(INDEX FAST FULL SCAN) 注意:PG系数据库没有这个功能
索引范围扫描(无回表)
索引范围扫描(有回表)
COUNT,SUM,AVG,MAX,MIN,DISTINCT,ORDER BY,HASH JOIN,分析函数
标量子查询,FILTER,SELECT 调用自定义函数
全表并行扫描
索引并行扫描
有索引情况下批量插入100W行性能
无索引情况下批量插入100W行性能
有索引情况下循环10W次单行插入性能
无索引情况下循环10W次单行插入性能
等等...不一一列举
上面列举了这么多基础算子,其实只要哪个国产数据库厂商能把全表扫描基础算子性能做到接近PG,那就很厉害了
最近收到了崖山23.5.1的测试包,做了个测试项目,暂且命名为《Oracle-PG-崖山全表扫描基础算子性能对比》
测试结果如下:
|------------|---|---|---|---|---|----------------|-----------|------------------|
| 测试场景 | SQL语句 ||||| Oracle11.2.0.4 | PG18.1 | YASHAN23.5.1 |
| 全表扫描+COUNT | select count(*) from test01; ||||| 00:00:00.82 | 00:01.467 | 00:00:00.510 |
| 全表扫描+COUNT | select count(*) from test01 where object_id>0; ||||| 00:00:01.25 | 00:03.234 | 00:00:02.376 |
| 全表扫描+聚合函数 | select count(object_id) from test01; ||||| 00:00:01.18 | 00:02.117 | 00:00:02.126 |
| 全表扫描+聚合函数 | select max(object_id) from test01; ||||| 00:00:01.37 | 00:03.087 | 00:00:02.992 |
| 全表扫描+聚合函数 | select min(object_id) from test01; ||||| 00:00:01.35 | 00:03.069 | 00:00:03.002 |
| 全表扫描+聚合函数 | select avg(object_id) from test01; ||||| 00:00:01.80 | 00:03.183 | 00:00:03.651 |
| 全表扫描+聚合函数 | select sum(object_id) from test01; ||||| 00:00:01.58 | 00:03.179 | 00:00:02.851 |
| 全表扫描+聚合函数 | select count(owner) from test01; ||||| 00:00:01.09 | 00:01.963 | 00:00:02.031 |
| 全表扫描+聚合函数 | select count(distinct object_id) from test01; ||||| 00:00:04.05 | 00:17.071 | 00:00:06.415 |
| 全表扫描+聚合函数 | select count(distinct owner) from test01; ||||| 00:00:02.88 | 00:08.740 | 00:00:03.635 |
| 全表扫描+聚合函数 | select owner,count(*) from test01 group by owner; ||||| 00:00:03.57 | 00:04.854 | 00:00:03.910 |
| 全表扫描+聚合函数 | select object_id,count(*) from test01 group by object_id; ||||| 00:00:05.35 | 00:09.818 | 00:00:05.896 |
测试说明:
1.3个库操作系统,底层硬件一模一样,排除环境干扰
2.Oracle设置alter system set "_serial_direct_read"=never;确保全表扫描不受直接路径读干扰
3.test01表体积5GB左右,Oracle buffer_cahce 设置12G,能够缓存表所有块
4.PG shared_buffers设置的32GB,32GB大于表体积*4,能够缓存表所有块
5.崖山DATA_BUFFER_SIZE设置32GB,之前DATA_BUFFER_SIZE设置的是18GB, alter session set statistics_level=all;
再set autot trace还是能看到有物理读,怀疑崖山buffer cache管理策略是抄的PG,要设置DATA_BUFFER_SIZE超过表体积*4才能完全避免物理读
6.崖山后续测试不能设置alter session set statistics_level=all; 不然从第三个SQL开始会导致性能变差
结论:
1.崖山对count(*)不带where条件全表扫描性能做了特殊优化,比Oracle还快
2.崖山对count(distinct xxx)场景做了特殊优化,比PG18强很多,GROUP BY场景也比PG18强一点,其他场景和PG18差异不大
3.不管是崖山还是PG,相比Oracle,一些场景还是比Oracle慢一倍,PG和崖山还得继续加油
4.终于看到一款国产数据库在全表扫描基础算子性能追上了原生PG,且在部分场景超越原生PG,值得大大的表扬