PL/SQL 块需要大量时间来执行

Posted

技术标签:

【中文标题】PL/SQL 块需要大量时间来执行【英文标题】:PL/SQL block taking lot of time to execute 【发布时间】:2014-04-04 06:36:23 【问题描述】:

我正在学习 PL/SQL 并编写了一个 PL/SQL 块,我将其粘贴在下面。 该块按预期运行,但完成该过程需要大量时间。 要检查我在两个表中运行了 10 条记录,需要 4 分钟。 之后,我尝试在大量数据上运行它,即使 5 小时后它也没有完成。 谁能指导我这里有什么问题以及如何提高性能。下面是我的 PL/SQL 块。

编辑:在 client_trans_vk1 中的 client_id 上没有为更新查询创建索引。这是罪魁祸首吗?

DECLARE
v_client_id test_vk.client_id%TYPE;
v_trans_amount account_bal.Bal_Am%TYPE;

cursor c_client
is select client_id,TRANS_AM as transaction_amount  from test_vk;

begin
  OPEN  c_client;
  LOOP
    FETCH c_client INTO v_client_id,v_trans_amount;
    BEGIN
    EXIT WHEN c_client%NOTFOUND;
     update client_trans_vk1 ca
       set ca.bal_amt = 0, ca.additional_AM = (ca.additional_AM + v_trans_amount) 
       where ca.client_id = v_client_id;
     commit;
    END;
  end LOOP;
  CLOSE c_client
end;

【问题讨论】:

【参考方案1】:

没有 EXIT from LOOP 语句,我很惊讶它竟然起作用了,它基本上是循环的 在最后一行无限。从游标中获取所有行后,您需要退出循环,如下所示:

DECLARE
v_client_id test_vk.client_id%TYPE;
v_trans_amount account_bal.Bal_Am%TYPE;

cursor c_client
is select client_id,TRANS_AM as transaction_amount  from test_vk;

begin
  OPEN  c_client;
  LOOP
    FETCH c_client INTO v_client_id,v_trans_amount;
    EXIT WHEN c_client%NOTFOUND;
    BEGIN
     update client_trans_vk1 ca
       set ca.bal_amt = 0, ca.additional_AM = (ca.additional_AM + v_trans_amount) 
       where ca.client_id = v_client_id;
     commit;
    END;
  end LOOP;
  CLOSE c_client
end;

【讨论】:

OP 确实说“即使在 5 小时后也没有完成” :) 感谢米哈伊尔和杰弗里。我确实在那里有退出声明。在 SO 中编辑问题时,它被错误地删除了。但遗憾的是问题仍然存在:( 米哈伊尔我接受你的回答。我有 EXIT 语句,但它不在 FETCH 和 BEGIN 之间,而是在 BEGIN 之后。感谢您指出。无论如何,我还在 client_trans_vk1 表中的 client_id 上创建了索引。现在你会惊讶我的 PL/SQL 块在 9.27 秒内执行......:)。无论如何,杰弗里,如果可以的话,我也会投票给你。

以上是关于PL/SQL 块需要大量时间来执行的主要内容,如果未能解决你的问题,请参考以下文章

SQLPLUS执行PL/SQL语句块

PL/SQL 过程块

使用来自 java 的值执行匿名 pl/sql 块文件

如何使用绑定变量使整个 PL/SQL 代码块动态化?

PL/SQL 包开始/结束块之间的代码何时执行?

oracle数据库之PL/SQL 块结构和组成元素