Заменить выборку итерации на BULK COLLECT - PullRequest
1 голос
/ 30 сентября 2011

Существует тип объекта, и таблица состоит из этих объектов. Итак, поехали:

create or replace type lpu.someobj_o as object
(      
  name VARCHAR2(75),     
  enroll_date DATE,
  id NUMBER(12)
)

CREATE OR REPLACE TYPE lpu."SOMEOBJ_T" IS TABLE OF someobj_o;

Есть также функция PL / SQL, которая работает в общем ETL-принципе . Вот фрагмент кода функции:

  for some_cursor_rec in some_cursor(startTime, recordInterval) loop
  open some_cur2(some_cursor_rec.name, some_cursor_rec.id);
  fetch some_cur2 into some_cursor_rec2;
  if some_cur2%rowcount > 0 then
    loop
      pipe row (
        lpu.someobj_o(
        id => some_cursor_rec2.id, 
        name => some_cursor_rec2.name, 
        enroll_date => some_cursor_rec2.enroll_date
      )
      );
      fetch some_cur2 into some_cursor_rec2;
      exit when some_cur2%notfound;
    end loop;      
  end if;
  close some_cur2;
end loop;

Хорошо, проблема в малой производительности. Как я могу увеличить скорость выполнения этой функции? Я прочитал, что BULK COLLECT должно улучшить производительность. Но как я могу использовать это в моем случае? Я попытался BULK COLLECT, но это дало мне ошибку, что тип коллекции неправильный. Заранее спасибо! Очень надеюсь на вашу помощь!

Ответы [ 2 ]

4 голосов
/ 30 сентября 2011

Если вам важна производительность, вам следует начать с объединения двух курсоров.

В данный момент вы выполняете запрос в some_cursor один раз, и вы выполняете запрос в курсоре some_cur2 каксколько раз в первом запросе выбраны строки .И это, скорее всего, ваше узкое место в производительности.

Если вы объедините два запроса в один запрос и создадите курсор для цикла (который выполняет запрос только один раз), то вы будете автоматически выполнять массовую выборку 100 строк свремя, так что, вероятно, не будет реальной необходимости вручную конвертировать его для массовой выборки.

С уважением,
Роб.

0 голосов
/ 30 сентября 2011

Вот базовый пример использования bulk collect into с типом объекта.

create or replace type someobj_o as object
(      
  name varchar2(75),     
  enroll_date date,
  id number(12)
);
/

create or replace type someobj_t is table of someobj_o;
/

create table someobj_table of someobj_o;

insert into someobj_table values(someobj_o('Joe', current_date, 100));
insert into someobj_table values(someobj_o('Jack', current_date, 101));
insert into someobj_table values(someobj_o('John', current_date, 102));

declare
  v_objs someobj_t;
begin
  select someobj_o(name, enroll_date, id)
    bulk collect into v_objs
    from someobj_table;

  dbms_output.put_line('number of objects in a collection = ' || v_objs.count);
end;
/

Обновление

То же, что и выше с курсором:

declare
  type objcur_t is ref cursor;
  v_objcur objcur_t;
  v_objs someobj_t;
begin
  open v_objcur for
    select someobj_o(name, enroll_date, id)
    from someobj_table;

  fetch v_objcur bulk collect into v_objs;

  close v_objcur;

  dbms_output.put_line('number of objects in a collection = ' || v_objs.count);
end;
/
...