简体   繁体   English

SQL%rowcount 导致 PL/SQL 性能下降

[英]PL/SQL performace hit with SQL%rowcount

I have a PL/SQL script in which I am updating some record and depending upon the result of this query I am updating another table.我有一个 PL/SQL 脚本,我正在其中更新一些记录,并根据此查询的结果更新另一个表。

In a loop I am executing below queries which can loop up to 100 000 records.在一个循环中,我正在执行以下查询,该查询最多可以循环 100 000 条记录。

update employee set dept='department' where empid=a.id;

IF SQL%rowcount = 1 THEN
    -- updating other table
END IF;

Is there any alternative logic to achieve this?是否有任何替代逻辑来实现这一目标?

Most probably there is another option.最有可能另一种选择。

From what you described, you're doing that in a loop which suggests that it affects only one row at a time (based on where clause and sql%rowcount = 1 ; if there were many rows, you'd check >= 1 ).根据您的描述,您是在循环中执行此操作,这表明它一次只影响一行(基于where子句和sql%rowcount = 1 ;如果有很多行,您将检查>= 1 ) . Such an approach usually means row-by-row which is slow-by-slow.这种方法通常意味着逐行缓慢。

See whether you can do that on sets , not single rows .看你是否能做到这一点上,而不是单一的行 Remove the loop entirely.完全取下环。

For example, if this is what you have now:例如,如果这是您现在所拥有的:

begin
  for cur_r in (select deptno, empno 
                from emp 
                where job = 'CLERK'
               ) 
  loop
    update emp set sal = sal + 100
      where empno = cur_r.empno;

    if sql%rowcount = 1 then
       update dept set
         dname = dname || 'x'
         where deptno = cur_r.deptno
    end if;
  end loop;
end;

rewrite it to将其改写为

begin
  update emp e set
    e.sal = e.sal + 100
    where e.job = 'CLERK';           --> condition from the cursor FOR loop

  update dept d set
    d.dname = d.dname || 'x'
    where d.deptno in (select e.deptno           --> SELECT used in
                       from emp e                --> cursor FOR
                       where e.job = 'CLERK'     --> loop
                      );
end;

Use an SQL collection and the RETURNING ... [BULK COLLECT] INTO clause of the UPDATE statement:使用 SQL 集合和UPDATE语句的RETURNING ... [BULK COLLECT] INTO子句

CREATE TYPE int_array IS TABLE OF NUMBER(10,0);

Then if you were using:然后,如果您使用的是:

BEGIN
  FOR a IN (
    SELECT id
    FROM   first_table
    WHERE  some_condition = 'MET'
  ) 
  LOOP
    update employee set dept='department' where empid=a.id;

    IF sql%rowcount = 1 THEN
       UPDATE other_table
       SET    something = 'X'
       WHERE  employee_id = a.id;
    END IF;
  END LOOP;
END;
/

Change it to:将其更改为:

DECLARE
  p_ids int_array;
BEGIN
  update employee
  set    dept = 'department'
  where  empid IN (
    SELECT id
    FROM   first_table
    WHERE  some_condition = 'MET'
  )
  RETURNING empid BULK COLLECT INTO int_array;

  UPDATE other_table
  SET    something = 'X'
  WHERE  employee_id MEMBER OF int_array;
END;
/

And you will have got rid of the loop entirely and directly use the primary keys that have been updated.您将完全摆脱循环并直接使用已更新的主键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM