PL / SQL производительность достигнута с SQL% строк - PullRequest
0 голосов
/ 06 января 2020

У меня есть сценарий PL / SQL, в котором я обновляю некоторую запись и в зависимости от результата этого запроса я обновляю другую таблицу.

В al oop я выполняю нижеуказанные запросы, которые Можно ли oop до 100 000 записей.

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

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

Есть ли альтернативные логики c для достижения этой цели?

Ответы [ 2 ]

3 голосов
/ 06 января 2020

Скорее всего, - это другой вариант.

Из того, что вы описали, вы делаете это в al oop, что предполагает, что он влияет только на одну строку за раз (на основе в предложениях where и sql%rowcount = 1; если бы было много строк, вы бы отметили >= 1). Такой подход обычно означает, что строка за строкой идет медленно-медленно.

Посмотрите, можете ли вы сделать это на множествах , а не на единственных строках . Удалите l oop полностью.

Например, если это то, что у вас есть сейчас:

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;

переписать его на

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;
2 голосов
/ 06 января 2020

Используйте коллекцию SQL и предложение RETURNING ... [BULK COLLECT] INTO оператора UPDATE:

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

Тогда, если вы использовали:

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;
/

Измените его на:

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;
/

И вы полностью избавитесь от l oop и напрямую воспользуетесь первичными ключами, которые были обновлены.

...