测试Oracle-PG-DM-崖山-openGauss游标LOOP性能

PLSQL开发应该尽量避免使用游标,乱用游标会引起严重性能问题

最近几年做过很多ORACLE EBS优化项目,除了乱写SQL导致性能问题之外,影响性能最大的就是乱用游标

如果是INSERT,直接INSERT INTO SELECT,或者INSERT /*+ PARALLEL(6) ENABLE_PARALLEL_DML */ SELECT...,不要用游标LOOP循环单行INSERT

如果是UPDATE,DELETE,为了避免大事务,可以用ROWID+批量游标,根据数据集大小1-10W行提交一次

如果是要做复杂的计算,可以用临时表存放SQL多表关联的中间结果集,不要游标套游标来做复杂计算

数据量少(10w行内),如果没有游标套游标,如果游标中没有复杂慢SQL,如果游标中没有胡乱调用复杂自定义函数,可以适当使用游标

数据量很少,爱咋咋用

虽然我们嘴上说要尽量避免使用游标,但是有时候很多PLSQL代码都已经写了10-20年了,里面大量使用了游标,木已成舟,不可能推翻重来了

现在来测试Oracle-PG-DM-崖山-openGauss游标LOOP性能,看看国产库游标LOOP性能和Oracle差距有多大

如果国产库游标LOOP性能和Oracle差距不大,就加测游标LOOP+INSERT,批量游标,如果性能差距太大就不测了,免得丢人

TEST01数据来自DBA_OBJECTS,重复512次,共4500W行,不创建索引

测试PLSQL代码如下

复制代码
begin
  for cur in (select object_id from test01) loop
   null;  ---无计算,测试纯LOOP性能
  end loop;
end;
/

declare
  v_cnt number := 0;
begin
  for cur in (select object_id from test01) loop
    v_cnt:=v_cnt+cur.object_id; ---带计算,测试LOOP循环计算性能
  end loop;
  dbms_output.put_line(v_cnt);
end;
/

开始测试(多次运行,确保TEST01被CACHE在内存中)

Oracle11.2.0.4

复制代码
SQL> begin
  for cur in (select object_id from test01) loop
   null;
  end loop;
end;
/  2    3    4    5    6  

PL/SQL procedure successfully completed.

Elapsed: 00:00:07.56

SQL> declare
  v_cnt number := 0;
begin
  for cur in (select object_id from test01) loop
    v_cnt:=v_cnt+cur.object_id;
  end loop;
  dbms_output.put_line(v_cnt);
end;
/  2    3    4    5    6    7    8    9  
1953663546368

PL/SQL procedure successfully completed.

Elapsed: 00:00:08.85

PG18

复制代码
postgres=# do $$
postgres$# declare
postgres$#   cur record;
postgres$# begin
postgres$#   for cur in select object_id from test01
postgres$#   loop
postgres$#     null;
postgres$#   end loop;
postgres$# end $$;
DO
Time: 9259.170 ms (00:09.259)

postgres=# do $$
postgres$# declare
postgres$#   v_cnt numeric := 0;
postgres$#   cur record;
postgres$# begin
postgres$#   for cur in select object_id from test01
postgres$#   loop
postgres$#     v_cnt := v_cnt + cur.object_id;
postgres$#   end loop;
postgres$#   raise notice 'Result: %', v_cnt;
postgres$# end $$;
NOTICE:  Result: 1953663546368
DO
Time: 15820.366 ms (00:15.820)

DM8

复制代码
SQL> begin
  for cur in (select object_id from test01) loop
   null;  
  end loop;
end;
/
2   3   4   5   6   
DMSQL executed successfully
used time: 00:00:17.230. Execute id is 604.

SQL> declare
  v_cnt number := 0;
begin
  for cur in (select object_id from test01) loop
    v_cnt:=v_cnt+cur.object_id; 
  end loop;
  dbms_output.put_line(v_cnt);
end;
/2   3   4   5   6   7   8   9   
DMSQL executed successfully
used time: 00:00:21.558. Execute id is 605.

崖山23.5.1

复制代码
SQL> begin
  for cur in (select object_id from test01) loop
   null;  
  end loop;
end;
/   2    3    4    5    6 

PL/SQL Succeed.

Elapsed: 00:00:17.487

SQL> declare
  v_cnt number := 0;
begin
  for cur in (select object_id from test01) loop
    v_cnt:=v_cnt+cur.object_id; 
  end loop;
  dbms_output.put_line(v_cnt);
end;
/   2    3    4    5    6    7    8    9 

PL/SQL Succeed.

Elapsed: 00:00:24.163

openGauss7.0

复制代码
openGauss=# begin
openGauss$#   for cur in (select object_id from test01) loop
openGauss$#    null;
openGauss$#   end loop;
openGauss$# end;
openGauss$# /
ANONYMOUS BLOCK EXECUTE
Time: 10391.383 ms

openGauss=# declare
openGauss-#   v_cnt number := 0;
openGauss-# begin
openGauss$#   for cur in (select object_id from test01) loop
openGauss$#     v_cnt:=v_cnt+cur.object_id;
openGauss$#   end loop;
openGauss$#   RAISE NOTICE 'Result: %', v_cnt;
openGauss$# end;
openGauss$# /
NOTICE:  Result: 1953663546368
ANONYMOUS BLOCK EXECUTE
Time: 26544.038 ms

测试结果汇总如下图所示:

结论:

Oracle游标LOOP循环性能最好,游标LOOP带计算性能损失1.29秒

PG游标LOOP循环性能很好,游标LOOP带计算性性能损失6.56秒

DM游标LOOP循环性能不好,游标LOOP带计算性能损失4.32秒

崖山游标LOOP循环性能不好,游标LOOP带计算性能损失6.67秒

openGauss游标LOOP性能很好,游标LOOP带计算性能差16.15秒

国产库在游标处理的性能上还有很大性能提升空间

相关推荐
蓝鸟19746 分钟前
Oracle 19c JSON_OBJECT 完全实战指南|嵌套、多行多列数组合并、空值踩坑、医保报文落地
数据库·oracle·json_arrayagg·多行转json数组·sql实战踩坑·数据库json拼装·json_object
一个天蝎座 白勺 程序猿23 分钟前
SQL Server数据迁移金仓性能优化实战:从慢SQL到系统瓶颈,一套组合拳打下来
sql·oracle·性能优化·kingbasees
其实防守也摸鱼1 天前
VS Code Git 工作树:解锁多分支并行开发新体验
数据库·git·安全·oracle·架构·自动化
ERD Online1 天前
MySQL/Oracle/PG/SQLServer 存量库一键逆向成关系图
mysql·oracle·sqlserver
奇树谦2 天前
《现代 Key-Value 数据库原理:从 B+Tree 到 LSM Tree》-第三篇:LMDB 深度解析二
数据库·oracle·lsm-tree
提笔了无痕2 天前
Agent 上下文管理详解、Context设计与构建
数据库·oracle·agent·context
沉下去,苦磨练!2 天前
Human‑in‑the‑Loop
数据库·oracle
小黑技术栈2 天前
web前端基础到入门——14day
前端·数据库·oracle
todoitbo3 天前
把发票台账接进 Codex:KingbaseES MCP 的一次只读风险排查实践
数据库·oracle·codex·kingbasees·mcp
暗暗别做白日梦3 天前
CompletableFuture 并发统计
网络·数据库·oracle