我测试了在相同软硬件条件下,openGauss、PostgreSQL、Oracle 和 MySQL 的 CPU 指令数消耗对比,急着想知道结果的可以直接跳到最后一部分看结果。
1. 测试环境说明
- 三种数据库均在同一台服务器上运行,内存 251G,CPU 为 Intel® Xeon® CPU E5-4650 v2 @ 2.40GHz(80核)。
- 采样期间,测试语句均已完成预热,数据完全在内存中处理(Buffer Pool / Buffer Cache)。
- 测试期间系统无其他高负载任务干扰。
2. Oracle Database 测试用例
2.1 建表与数据初始化
使用 CONNECT BY 语法进行高速数据生成。
-- 清理环境
DROP TABLE t_cpu_test PURGE;
-- 建表并直接插入 100万 行数据
CREATE TABLE t_cpu_test NOLOGGING AS
SELECT
rownum AS id,
rpad('X', 50, 'X') AS info,
sysdate AS created_time
FROM
dual
CONNECT BY
level <= 1000000;
-- 添加主键 (这对索引扫描至关重要)
ALTER TABLE t_cpu_test ADD CONSTRAINT pk_t_cpu_test PRIMARY KEY (id);
-- 收集统计信息
BEGIN
dbms_stats.gather_table_stats(ownname => USER, tabname => 'T_CPU_TEST');
END;
/
-- 验证数据量
SELECT count(*) FROM t_cpu_test;
2.2 获取操作系统进程号 (SPID)
Oracle 为多进程架构,需要定位当前会话对应的 OS 进程 ID。
SELECT p.spid, s.sid, s.serial#
FROM v$session s, v$process p
WHERE s.paddr = p.addr
AND s.sid = USERENV('SID');
本次测试获取到的 SPID: 64689
2.3 性能监控 (Linux Shell)
在操作系统侧执行 perf 命令,监控该进程在采样窗口内的 CPU 指令消耗。
perf stat -e instructions:u -p 64689
2.4 Oracle 测试结果
oracle@Yuan ~$ sudo perf stat -e instructions:u -p 64689
^C
Performance counter stats for process id '64689':
105,023 instructions:u
2.411828207 seconds time elapsed
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. openGauss 测试用例
3.1 建表与数据初始化
使用 PostgreSQL/openGauss 标准的 generate_series 函数生成数据。
SQL
-- 清理环境
DROP TABLE IF EXISTS t_cpu_test;
-- 创建表结构
CREATE TABLE t_cpu_test (
id integer,
info varchar(50),
created_time timestamp
);
-- 插入 100万 行数据
INSERT INTO t_cpu_test
SELECT
n,
rpad('X', 50, 'X'),
now()
FROM
generate_series(1, 1000000) as n;
-- 添加主键
ALTER TABLE t_cpu_test ADD PRIMARY KEY (id);
-- 收集统计信息
ANALYZE t_cpu_test;
-- 验证数据量
SELECT count(*) FROM t_cpu_test;
-- 预热/功能检查
SELECT * FROM t_cpu_test WHERE id = 1234;
3.2 获取操作系统线程号 (LWTID)
openGauss 为单进程多线程架构,需要通过 pg_thread_wait_status 视图关联查找当前会话底层的轻量级线程 ID (LWTID)。
SELECT lwtid
FROM pg_thread_wait_status
WHERE sessionid = (SELECT sessionid FROM pg_stat_activity WHERE pid = pg_backend_pid());
本次测试获取到的 LWTID: 49936
3.3 性能监控 (Linux Shell)
在操作系统侧执行 perf 命令,监控该线程的 CPU 指令消耗。
perf stat -e instructions:u -t 49936
3.4 openGauss 测试结果
[root@dell ~]# perf stat -e instructions:u -t 49936
^C
Performance counter stats for thread id '49936':
302,869 instructions:u
2.617229382 seconds time elapsed

4. PostgreSQL 9.2 测试用例
由于openGauss是基于PostgreSQL 9.2的基础上进行开发的,我们再增加在这个版本上的测试案例:

5. PostgreSQL 18.1 测试用例
PostgreSQL的命令基本和openGauss一致,只是获取进程号的指令不同:
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
46606
(1 row)
[root@dell ~]# perf stat -e instructions:u -p 46606
^C
Performance counter stats for process id '46606':
108,145 instructions:u
2.636957141 seconds time elapsed

6. MySQL 8.0 测试用例
6.1 建表与数据初始化
由于 MySQL 8.0 支持递归 CTE,可以使用以下语法快速生成 100 万行数据。
-- 清理环境
DROP TABLE IF EXISTS t_cpu_test;
-- 创建表结构
CREATE TABLE t_cpu_test (
id INT PRIMARY KEY,
info VARCHAR(50),
created_time DATETIME
) ENGINE=InnoDB;
-- 插入 100万 行数据 (设置递归深度限制以支持100万行)
SET SESSION cte_max_recursion_depth = 1000000;
INSERT INTO t_cpu_test
WITH RECURSIVE seq AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM seq WHERE n < 1000000
)
SELECT
n,
RPAD('X', 50, 'X'),
NOW()
FROM seq;
-- 收集统计信息
ANALYZE TABLE t_cpu_test;
6.2 获取操作系统线程号 (LWTID)
在 MySQL 中,可以通过 performance_schema 获取当前连接对应的操作系统线程 ID。
SELECT THREAD_OS_ID
FROM performance_schema.threads
WHERE PROCESSLIST_ID = CONNECTION_ID();
获取到的 LWTID 为: 30129
[root@dell ~]# perf stat -e instructions:u -t 30129
^C
Performance counter stats for thread id '30129':
91,101 instructions:u
3.136717427 seconds time elapsed

6.3 性能监控与结果示例
Bash
# 在执行 SELECT * FROM t_cpu_test WHERE id = 123456 时进行采样
sudo perf stat -e instructions:u -t 74098
7. MariaDB 10.11 测试用例
7.1 建表与数据初始化
MariaDB 拥有非常高效的 sequence 存储引擎,生成数据最为快捷。
-- 清理环境
DROP TABLE IF EXISTS t_cpu_test;
-- 创建表结构
CREATE TABLE t_cpu_test (
id INT PRIMARY KEY,
info VARCHAR(50),
created_time DATETIME
) ENGINE=InnoDB;
-- 使用 MariaDB 特有的 seq 引擎插入 100万 行数据
INSERT INTO t_cpu_test
SELECT
seq,
RPAD('X', 50, 'X'),
NOW()
FROM seq_1_to_1000000;
-- 收集统计信息
ANALYZE TABLE t_cpu_test;
7.2 获取操作系统线程号 (LWTID)
MariaDB 的方法与 MySQL 类似。
SELECT THREAD_OS_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = CONNECTION_ID();
获取到的 LWTID 为: 45642
7.3 性能监控与结果示例
Bash
sudo perf stat -e instructions:u -t 45642
^C
Performance counter stats for thread id '45642':
84,393 instructions:u
3.452852099 seconds time elapsed

8. 结果对比与分析
将各数据库在采样窗口内的数据汇总如下(以 PostgreSQL 18.1 为 1.00x 基准):
| 数据库版本 | 架构模式 | CPU 指令数 (Instructions) | 相对倍数 |
|---|---|---|---|
| MariaDB 10.11 | 多线程 | 84,393 | 0.78x |
| MySQL 8.0 | 多线程 | 91,101 | 0.84x |
| Oracle 19c | 多进程 | 105,023 | 0.97x |
| PostgreSQL 18.1 | 多进程 | 108,145 | 1.00x |
| PostgreSQL 9.2 | 多进程 | 119,349 | 1.10x |
| openGauss 6.0.3 | 多线程 | 302,869 | 2.80x |
分析结论:
- PostgreSQL 与 Oracle 的高度一致性。
- PostgreSQL 18.1 (10.8万) 比 PostgreSQL 9.2 (11.9万) 的指令数更少,效率提升了约 10%。
- MySQL 和 MariaDB 消耗的指令最少,它们都是索引组织表架构,执行计划中少一步。
- openGauss 的指令数消耗大约是 PostgreSQL 原生版本 和 Oracle 的 3 倍。