Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Ускорить выполнение следующего кода  [new]
Kozerog_2
Member

Откуда:
Сообщений: 151
Подскажите можно ли как-то ускорить выполнение следующего кода

declare batnum varchar2(50);
BEGIN
FOR c1_rec IN (SELECT sub_no FROM submis1 WHERE identifier like 'TEST%') LOOP
batnum := submission.get_batch_num (c1_rec.sub_no);
h2.search.hnp_delete_submission(c1_rec.sub_no);
DELETE FROM batch_fragment WHERE bat_no in (batnum);
DELETE FROM batch_log WHERE bat_no in (batnum);
DELETE FROM batch WHERE bat_no in (batnum);
DELETE FROM engine_batch WHERE bat_no in (batnum);
DELETE FROM batch_control WHERE bat_no in (batnum);
COMMIT;
END LOOP;
END;

Или как-то решить эту же задачу по другому, но быстрее ?
7 окт 08, 15:53    [6274763]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
stax..
Guest
удалять с помощью forall
ps
не понял bat_no in (batnum);
почему не =
но ето неважно
......
stax
7 окт 08, 16:06    [6274887]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Destined
Member

Откуда: Краснодар
Сообщений: 76
Kozerog_2
Подскажите можно ли как-то ускорить выполнение следующего кода

declare batnum varchar2(50);
BEGIN
FOR c1_rec IN (SELECT sub_no FROM submis1 WHERE identifier like 'TEST%') LOOP
batnum := submission.get_batch_num (c1_rec.sub_no);
h2.search.hnp_delete_submission(c1_rec.sub_no);
DELETE FROM batch_fragment WHERE bat_no in (batnum);
DELETE FROM batch_log WHERE bat_no in (batnum);
DELETE FROM batch WHERE bat_no in (batnum);
DELETE FROM engine_batch WHERE bat_no in (batnum);
DELETE FROM batch_control WHERE bat_no in (batnum);
COMMIT;
END LOOP;
END;

Или как-то решить эту же задачу по другому, но быстрее ?


select bulk collect + forall
7 окт 08, 16:08    [6274903]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Destined
Member

Откуда: Краснодар
Сообщений: 76
Destined
Kozerog_2
Подскажите можно ли как-то ускорить выполнение следующего кода

declare batnum varchar2(50);
BEGIN
FOR c1_rec IN (SELECT sub_no FROM submis1 WHERE identifier like 'TEST%') LOOP
batnum := submission.get_batch_num (c1_rec.sub_no);
h2.search.hnp_delete_submission(c1_rec.sub_no);
DELETE FROM batch_fragment WHERE bat_no in (batnum);
DELETE FROM batch_log WHERE bat_no in (batnum);
DELETE FROM batch WHERE bat_no in (batnum);
DELETE FROM engine_batch WHERE bat_no in (batnum);
DELETE FROM batch_control WHERE bat_no in (batnum);
COMMIT;
END LOOP;
END;

Или как-то решить эту же задачу по другому, но быстрее ?


select bulk collect + forall


Плюс конечно коммит убрать.
7 окт 08, 16:08    [6274909]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
semenar
Member

Откуда: Днепропетровск
Сообщений: 3308
Блог
А ты задумывался если у тебя в for будет миллион записей? И на каждой commit?
7 окт 08, 16:08    [6274910]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
stax..
Guest
semenar
А ты задумывался если у тебя в for будет миллион записей? И на каждой commit?

ну с умом ж бюлкати и комитить
......
stax
7 окт 08, 16:25    [6275087]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Destined
Destined
select bulk collect + forall
Плюс конечно коммит убрать.
А Вы сможете его там (на каждом шаге) оставить? :)
7 окт 08, 16:34    [6275148]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Destined
Member

Откуда: Краснодар
Сообщений: 76
Jannny
Destined
Destined
select bulk collect + forall
Плюс конечно коммит убрать.
А Вы сможете его там (на каждом шаге) оставить? :)


Я не знаю логики таблиц, но интуитивно не вижу, что мне может помешать это сделать, кроме здравого смысла.

Здесь я имею в виду коммит между пятью forall.
7 окт 08, 16:39    [6275197]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Destined
Jannny
Destined
Destined
select bulk collect + forall
Плюс конечно коммит убрать.
А Вы сможете его там (на каждом шаге) оставить? :)
Я не знаю логики таблиц, но интуитивно не вижу, что мне может помешать это сделать, кроме здравого смысла.

Здесь я имею в виду коммит между пятью forall.
ИМХО Вы фантазируете, если у автора это не было таких коммитов изначально, то совершенно непонятно, с чего бы ему это потом сделать...
7 окт 08, 16:42    [6275231]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Пилот Пиркс
Member

Откуда: Москва
Сообщений: 352
Kozerog_2

h2.search.hnp_delete_submission(c1_rec.sub_no);
DELETE FROM batch_fragment WHERE bat_no in (batnum);
DELETE FROM batch_log WHERE bat_no in (batnum);
DELETE FROM batch WHERE bat_no in (batnum);
DELETE FROM engine_batch WHERE bat_no in (batnum);
DELETE FROM batch_control WHERE bat_no in (batnum);

Судя по всему вы пытаетесь воспроизвести поведение внешних ключей. Мб использовать оракл для этого? foreign key .. on delete cascade.
7 окт 08, 16:44    [6275258]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Kozerog_2
Member

Откуда:
Сообщений: 151
Правильно ли модифицирован код ?
(Не ругайтесь - я новичок в Oracle)
начальный код написан не мной, перебирается 20 000 тыс записей,
по оценке процедура работет более 10 часов

declare batnum varchar2(50);
BEGIN
select c1_rec bulk collect into tab_emp from submission
where (identifier like 'TST%' and rownum<=100);

FORALL I IN tab_emp.first..tab_emp.last
BEGIN
batnum := submission.get_batch_num (c1_rec.sub_no);
search.delete_submission(c1_rec.sub_no);
DELETE FROM batch_fragment WHERE bat_no in (batnum);
DELETE FROM batch_log WHERE bat_no in (batnum);
DELETE FROM batch WHERE bat_no in (batnum);
DELETE FROM engine_batch WHERE bat_no in (batnum);
DELETE FROM batch_control WHERE bat_no in (batnum);
END;
COMMIT;
END;
7 окт 08, 16:45    [6275260]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Jannny
Member

Откуда: Спб
Сообщений: 6424
Kozerog_2
Правильно ли модифицирован код ?
А Вы попробуете это откомпилировать - ответ получите незамедлительно :)
7 окт 08, 16:51    [6275310]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Destined
Member

Откуда: Краснодар
Сообщений: 76
Jannny
Destined
Jannny
Destined
Destined
select bulk collect + forall
Плюс конечно коммит убрать.
А Вы сможете его там (на каждом шаге) оставить? :)
Я не знаю логики таблиц, но интуитивно не вижу, что мне может помешать это сделать, кроме здравого смысла.

Здесь я имею в виду коммит между пятью forall.
ИМХО Вы фантазируете, если у автора это не было таких коммитов изначально, то совершенно непонятно, с чего бы ему это потом сделать...


А с чего бы ему ставить в цикле коммит? :)
7 окт 08, 17:09    [6275463]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Kovalchuk Vitaly V
Member

Откуда: ненька Україна
Сообщений: 463
Я бы переписал так:
declare
  type tab_batnum is table of varchar2(50) index by binary_integer;
  type tab_subno is table of submis1.sub_no%TYPE index by binary_integer;
  v_batnums tab_batnum;
  v_subno   tab_subno;
  cursor c_submis1 IS
    SELECT sub_no FROM submis1 WHERE identifier like 'TEST%';
BEGIN
  OPEN c_submis1;
  LOOP
    FETCH c_submis1 BULK COLLECT
      INTO v_subno LIMIT 1000;
    EXIT WHEN c_submis1%NOTFOUND OR v_subno.COUNT = 0;
    FOR i IN v_subno.FIRST .. v_subno.LAST LOOP
      v_batnums(i) := submission.get_batch_num(v_subno(i));
      h2.search.hnp_delete_submission(v_subno(i));
    END LOOP;
  
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_fragment WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_log WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM engine_batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_control WHERE bat_no = v_batnums(i);
  END LOOP;
  CLOSE c_submis1;
  COMMIT;
END;
8 окт 08, 16:09    [6280451]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
RA\/EN
Member

Откуда:
Сообщений: 3659
Kovalchuk Vitaly V
Я бы переписал так:
declare
  type tab_batnum is table of varchar2(50) index by binary_integer;
  type tab_subno is table of submis1.sub_no%TYPE index by binary_integer;
  v_batnums tab_batnum;
  v_subno   tab_subno;
  cursor c_submis1 IS
    SELECT sub_no FROM submis1 WHERE identifier like 'TEST%';
BEGIN
  OPEN c_submis1;
  LOOP
    FETCH c_submis1 BULK COLLECT
      INTO v_subno LIMIT 1000;
    EXIT WHEN c_submis1%NOTFOUND OR v_subno.COUNT = 0;
    FOR i IN v_subno.FIRST .. v_subno.LAST LOOP
      v_batnums(i) := submission.get_batch_num(v_subno(i));
      h2.search.hnp_delete_submission(v_subno(i));
    END LOOP;
  
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_fragment WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_log WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM engine_batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_control WHERE bat_no = v_batnums(i);
  END LOOP;
  CLOSE c_submis1;
  COMMIT;
END;


SQL> declare
  2    TYPE tt IS TABLE OF NUMBER INDEX by BINARY_INTEGER;
  3    c SYS_REFCURSOR;
  4    t tt;
  5  begin
  6    OPEN c FOR 'select rownum  from all_objects where rownum<=15';
  7    LOOP
  8      FETCH c BULK COLLECT INTO t LIMIT 10;
  9      EXIT WHEN c%NOTFOUND OR t.count() = 0;
 10      dbms_output.put_line(t.first||'..'||t.last||' ('||t(t.last)||')');
 11    END LOOP;
 12    dbms_output.put_line('========');
 13    OPEN c FOR 'select rownum  from all_objects where rownum<=15';
 14    LOOP
 15      FETCH c BULK COLLECT INTO t LIMIT 5;
 16      EXIT WHEN c%NOTFOUND OR t.count() = 0;
 17      dbms_output.put_line(t.first||'..'||t.last||' ('||t(t.last)||')');
 18    END LOOP;
 19  end;
 20  /
 
1..10 (10)
========
1..5 (5)
1..5 (10)
1..5 (15)
 
PL/SQL procedure successfully completed
 
SQL> 
8 окт 08, 16:49    [6280828]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Пилот Пиркс
Member

Откуда: Москва
Сообщений: 352
RA\/EN
1..10 (10)
========
1..5 (5)
1..5 (10)
1..5 (15)

Сам только недавно это заметил) Переведу на русский.
Если используется FETCH .. BULK COLLECT .. LIMIT то EXIT WHEN надо ставить перед END LOOP :)
8 окт 08, 17:37    [6281234]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
Kovalchuk Vitaly V
Member

Откуда: ненька Україна
Сообщений: 463
Забыл что хвост пропадает :-) Тогда уж лучше так.

declare
  type tab_batnum is table of varchar2(50) index by binary_integer;
  type tab_subno is table of submis1.sub_no%TYPE index by binary_integer;
  v_batnums tab_batnum;
  v_subno   tab_subno;
  cursor c_submis1 IS
    SELECT sub_no FROM submis1 WHERE identifier like 'TEST%';
BEGIN
  OPEN c_submis1;
  LOOP
    FETCH c_submis1 BULK COLLECT
      INTO v_subno LIMIT 1000;
    EXIT WHEN v_subno.COUNT = 0;
    FOR i IN v_subno.FIRST .. v_subno.LAST LOOP
      v_batnums(i) := submission.get_batch_num(v_subno(i));
      h2.search.hnp_delete_submission(v_subno(i));
    END LOOP;
  
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_fragment WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_log WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM engine_batch WHERE bat_no = v_batnums(i);
    FORALL i IN v_batnums.FIRST .. v_batnums.LAST
      DELETE FROM batch_control WHERE bat_no = v_batnums(i);
    EXIT WHEN c_submis1%NOTFOUND;
  END LOOP;
  CLOSE c_submis1;
  COMMIT;
END;
8 окт 08, 19:02    [6281661]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
bon_pary
Member

Откуда:
Сообщений: 15
SELECT sub_no FROM submis1 WHERE identifier like 'TEST%'
сколько этот запрос отрабатыает? сразу отклик дает или секунды за 3 ?
8 окт 08, 19:10    [6281695]     Ответить | Цитировать Сообщить модератору
 Re: Ускорить выполнение следующего кода  [new]
KoTTT
Member

Откуда: Екб
Сообщений: 1511
Пилот Пиркс
RA\/EN
1..10 (10)
========
1..5 (5)
1..5 (10)
1..5 (15)

Сам только недавно это заметил) Переведу на русский.
Если используется FETCH .. BULK COLLECT .. LIMIT то EXIT WHEN надо ставить перед END LOOP :)

EXIT WHEN #.COUNT = 0 можно ставить и сразу после фетча.
Но работает корректно только начиная с 9-ки. 8-ка у меня нагло не выходила по этому условию из цикла.
9 окт 08, 04:50    [6282432]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить