[英]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.