Ускорить loop... forall не с dml?

loopforall
Дата: 18.12.2012 09:45:38
Добрый день.
Есть потребность сформировать скрипт в clob из столбцов таблицы.
В таблице идет выборка по 100К строк.
Написала процедуру, но сам процесс удручает своей медлительностью.
Подскажите, пожалуйста, как переписать, чтобы ускорить работу?

function print_xx (p_id number) return clob
is
x clob;
begin
    for i in ( select * from TT where A = p_id order by idx )
    LOOP
    x:=x||'begin '||
    ''''||to_char(i.a) ||''', '||
    ''''||to_char(i.b) ||''', '||
    ''''||to_char(i.c) ||''', '||
    ''''||to_char(i.d) ||'''); commit; end;'|| UTL_TCP.crlf ||'/'||UTL_TCP.crlf;
    END LOOP;
x:= x||'quit;';
return x;    
end;    

Смотрела в сторону http://psoug.org/reference/array_processing.html, но там должен быть DML после FORALL.
Еще думала коммитить каждые n строк.
Артем П.
Дата: 18.12.2012 10:07:31
Возможно так? Сэкономит возможно пару секунд.
function print_xx (p_id number) return clob
is
x clob;
begin
    dbms_lob.createTemporary(x, true);
    for i in ( select * from TT where A = p_id order by idx )
    LOOP
    dbms_lob.append(x,'begin '||
    ''''||to_char(i.a) ||''', '||
    ''''||to_char(i.b) ||''', '||
    ''''||to_char(i.c) ||''', '||
    ''''||to_char(i.d) ||'''); commit; end;'|| UTL_TCP.crlf ||'/'||UTL_TCP.crlf);
    END LOOP;
    dbms_lob.append(x,'quit;');
return x;    
end;  


А в таблице ТТ поле, по которому идет отбор является индексом?
loopforall
Дата: 18.12.2012 10:09:04
Спасибо.
Да, это первичный ключ, сам запрос не тяжел.
-2-
Дата: 18.12.2012 10:11:59
loopforall
Да, это первичный ключ, сам запрос не тяжел.
ты сам то понял, что наваял?
loopforall
Дата: 18.12.2012 10:14:51
Да :).
По делу есть че?
Артем П.
Дата: 18.12.2012 10:16:01
loopforall,

Кстати и еще вопрос, в таблице ТТ поля только a,b,c,d? Если нет, то лучше заменить
for i in ( select * from TT where A = p_id order by idx )

на
for i in ( select a,b,c,d from TT where A = p_id order by idx )
Изя Кацман
Дата: 18.12.2012 10:40:39
Попробуй так - отдай почти всю обработку SQL-движку - меньше переключений контекста.
И тащить из пакета UTL_TCP одну константу тоже нет смысла. Ты же можешь сама такую константу сделать, камрад
function print_xx (p_id number) return clob
is
x clob;
crlf CONSTANT VARCHAR(2) := CHR(13)||CHR(10); 
CURSOR cur IS
   SELECT 'begin '||
    ''''||to_char(a) ||''', '||
    ''''||to_char(b) ||''', '||
    ''''||to_char(c) ||''', '||
    ''''||to_char(d) ||'''); commit; end;'|| crlf ||'/'||crlf AS str
   FROM from TT 
   where A = print_xx.p_id 
   order by idx;
begin
   for i in cur LOOP
      x := x || i.str;
   END LOOP;
   x:= x || 'quit;';
return x;    
end;    

loopforall
В таблице идет выборка по 100К строк.
Об етом подробнее расскажи, камрад

loopforall
Еще думала коммитить каждые n строк.
Ето уже к выполнению твоего скрипта относится
Артем П.
Дата: 18.12.2012 10:45:28
Изя Кацман,

Если длина
'begin '||
    ''''||to_char(a) ||''', '||
    ''''||to_char(b) ||''', '||
    ''''||to_char(c) ||''', '||
    ''''||to_char(d) ||'''); commit; end;'|| crlf ||'/'||crlf

может превышать 4000 символов, то так не получится)
По делу
Дата: 18.12.2012 10:45:47
loopforall
Да :).
По делу есть че?


Интересный выхлоп
begin 'Петя','Коля','Вася','Лена'); commit; end;
/
begin 'Коля','Вася','Лена','Петя'); commit; end;
/


Ну а по делу:

1) Генерация скрипта на основе данных таблицы - сам подход сомнителен. Смеситель с сепаратором.
2) Если все равно надо, через агрегатные функции конкатенации строк должно работать быстрее (ИМХО).
Sayan Malakshinov
Дата: 18.12.2012 10:54:07
Артем П.
может превышать 4000 символов, то так не получится)
замени на to_clob