Повышение производительности при применении FORALL
Стивен Фернстайн
Источник: Рекомендации
RevealNet (группа PL/SQL) за апрель 2001,(http://128.121.241.221/Pipelines/PLSQL/tips.htm)
Improving Performance with FORALL, by Steven
Feuerstein
Благодарю Jeff Thomas (jsthomas@ixl.com)
Недавно я опробовал опцию
"Bulk Binding" ("Массовое Связывание") в Oracle 8.1.6 и был
поражен повышением производительности. Не прав будет тот разработчик, который
захочет познакомиться с этой возможностью. Свой небольшой эксперимент я оформил
в виде пакета и теперь представляю вам результат. Безусловно, ваши результаты
будут другими, но отправная точка должна быть вполне понятна. Ниже показаны
скрипты и выходные листинги как для обычного PL/SQL-программирования, так и для
использования FORALL-метода.
SQL Script
set echo onset feedback onspool forall /*
Простой тест на время выполнения
массового связывания при использовании FORALL. Покажем, что этот МЕТОД быстрее.
Для иллюстрации перегрузим 100,000
записей из plsql-таблицы в таблицу базы данных. Для этого имеются два способа,
как показано ниже.
DDL-предложение для таблицы примера: drop table test1; create table test1 (testnum number);*/
Пример1:
Обычное применение PL/SQL без использования массового связываеия (BULK BIND)
set timing on DECLAREtype t1_type is table of test1.testnum%type index by binary_integer;t1_tab t1_type;t1_idx binary_integer := 0; BEGIN -- загрузка plsql-таблицы
FOR n in 1 .. 100000LOOP t1_tab(n) := n; t1_idx := t1_idx + 1;END LOOP; -- загрузка db-таблицы
FOR n in 1 .. t1_idxLOOP insert into test1 (testnum) values (t1_tab(n));END LOOP; END;/ set timing offselect count(*) from test1;truncate table test1 reuse storage;set timing on
Пример2:
Использование
FORALL
DECLAREtype t1_type is table of test1.testnum%type index by binary_integer;t1_tab t1_type;t1_idx binary_integer := 0; BEGIN -- загрузка plsql-таблицы
FOR n in 1 .. 100000LOOP t1_tab(n) := n; t1_idx := t1_idx + 1;END LOOP; FORALL n in 1 .. t1_idx insert into test1 (testnum) values (t1_tab(n)); END;/ set timing offselect count(*) from test1;truncate table test1 reuse storage; spool off
Выходной листинг
Пример1:
Обычное применение PL/SQL без
использования массового связываеия (BULK BIND)
set timing on DECLARE 2 type t1_type is table of test1.testnum%type index by binary_integer; 3 t1_tab t1_type; 4 t1_idx binary_integer := 0; 5 6 BEGIN 7 8 -- load the plsql table 9 FOR n in 1 .. 100000 10 LOOP 11 t1_tab(n) := n; 12 t1_idx := t1_idx + 1; 13 END LOOP; 14 15 -- load the db table 16 FOR n in 1 .. t1_idx 17 LOOP 18 insert into test1 (testnum) values (t1_tab(n)); 19 END LOOP; 20 21 END; 22 / PL/SQL procedure successfully completed. Elapsed: 00:00:25.97 set timing offselect count(*) from test1; COUNT(*)-------- 100000 1 row selected. truncate table test1 reuse storage; Table truncated. set timing on
Пример2:
Использование FORALL
DECLARE
2 type t1_type is table of test1.testnum%type index by binary_integer;
3 t1_tab t1_type; 4 t1_idx binary_integer := 0; 5 6 BEGIN 7 8 -- load the plsql table 9 FOR n in 1 .. 100000 10 LOOP 11 t1_tab(n) := n; 12 t1_idx := t1_idx + 1; 13 END LOOP; 14 15 FORALL n in 1 .. t1_idx 16 insert into test1 (testnum) values (t1_tab(n)); 17 18 END; 19 / PL/SQL procedure successfully completed. Elapsed: 00:00:01.73 set timing offselect count(*) from test1; COUNT(*)-------- 100000 1 row selected. truncate table test1 reuse storage; Table truncated. spool off