测试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秒

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

相关推荐
XDHCOM17 小时前
ORA-32484重复列名错误,ORACLE数据库CYCLE子句故障修复与远程处理方案
数据库·oracle
一博一言17 小时前
Oracle高版本Version_Count问题处理排查
oracle·dba
LilySesy19 小时前
【与AI+】英语day4——数据库与性能优化
数据库·oracle·性能优化·sap·abap·自动翻译
余佬学数据库19 小时前
Error 57 initializing SQL*Plus Error loading message shared library
oracle
Yana.nice21 小时前
MySQL 事务的四大特性(ACID)
数据库·mysql·oracle
小小程序员.¥21 小时前
oracle--视图、序列、索引
服务器·数据库·oracle
zzh0811 天前
PG数据库日常应用
数据库·oracle
Trouvaille ~1 天前
【MySQL篇】表的操作:数据的容器
linux·数据库·mysql·oracle·xshell·ddl·表的操作
麦聪聊数据1 天前
数据库安全与运维管控(一):MySQL、PG与Oracle原生审计机制对比
运维·数据库·mysql·oracle
小小程序员.¥1 天前
oracle--plsql块、存储过程、存储函数
数据库·sql·oracle