Программирование >>  Oracle 

1 ... 273 274 275 [ 276 ] 277 278 279 ... 469


1240

Глава 16

INSERT INTO T Q4 (A,B,C) VALUES (:Ы,:Ь2,:ЬЗ)

call count cpu elapsed disk query current

Parse

0.07

0.04

Как видите, подпрограмме, использующей средства пакета DBMS SQL, хватило всего одного разбора, а вот при использовании встроенного динамического SQL анализировать операторы пришлось 400 раз. В загруженной системе, где одновременно работает множество пользователей, это может существенно снизить производительность. Поскольку избежать избыточнгх разборов можно и соответствующий код с использованием средств пакета DBMS SQL не намного сложнее, я считаю оптимальным при решении подобного рода задач использовать DBMS SQL. Хотя код и сложнее, но для обеспечения более высокой масштабируемости я бы использовал именно его.

Если сравнить результаты процедур, не обрабатывающих массивы, оказывается, что они существенно хуже:

BEGIN load data.dbmssql noarray(t, 10000); END;

call

count

elapsed

disk

query

current

Parse

0.00

0.00

Execute

7.66

7.68

Fetch

0.00

0.00

total

7.66

7.68

BEGIN load data.native dynamic noarray(t.

10000);

END;

call

count

elapsed

disk

query

current

rows

Parse

0.00

0.00

Execute

6.15

6.25

Fetch

0.00

0.00

total

6.15

6.25

Несомненно, имеет смысл использовать встроенный динамический SQL. Но и без массивов я все равно использовал бы средства пакета DBMS SQL. И вот почему:

insert into t q2 (a, b, c) values (:a, :b, :c)

call count cpu elapsed disk query current rows

Parse 1 0.00 0.00 0

insert into t q3 (a, b, c) values (:a, :b, call count cpu elapsed disk

Parse

10000

1.87

1.84

query

current

Оказывается, что при использовании встроенного динамического SQL пришлось выполнить 10000 мягких разборов, и лишь один - при использовании пакета DBMS SQL В многопользовательской среде реализация на основе пакета DBMS SQL окажется намного более масштабируемой.

rows

rows



Динамический SQL 1241

Аналогичные результаты можно получить и при обработке множества строк, выдаваемых по динамически формируемому запросу. Обычно данные можно выбирать из кур-сорн]х переменн1х массивами, но только из строго типизированных. Это такие курсор-н1е переменные, структура которых известна на этапе компиляции. Встроенный динамический SQL поддерживает использование только слабо типизированных курсор-н]х переменн1х и поэтому не поддерживает множественную выборку, BULK COLLECT. Если попытаться выполнить оператор BULK COLLECT для динамически открытой курсорной переменной, будет получено сообщение об ошибке:

ORA-01001: Invalid Cursor

Вот сравнение двух процедур, выбирающих и подсчитывающих все строки из представления ALL OBJECTS. Процедура, использующая средства пакета DBMS SQL и обрабатывающая массивы, работает почти вдвое быстрее:

scott@TKYTE816> create or replace procedure nativedynamicselect

2 as

3 type rc is ref cursor;

4 l cursor rc;

5 l oname varchar2(255);

6 l cnt number := 0;

7 l start number default dbms utility.get time;

8 begin

9 open l cursor for select object name from all objects; 10

11 loop

12 fetch l cursor into l oname;

13 exit when l cursor%notfound;

14 l cnt := l cnt+l;

15 end loop; 16

17 close l cursor;

18 dbms output.put line(L cnt rows processed);

19 dbmsoutput.putline

20 (round((dbms utility.get time-l start)/100, 2) 11 seconds);

21 exception

22 when others then

23 if (l cursor%isopen)

24 then

25 close l cursor; 2 6 end if;

27 raise;

28 end;

29 / Procedure created.

scott@TKIE816> create or replace procedure dbmssqlselect

2 as

3 l theCursor integer default dbms sql.open cursor;

4 l columnValue dbms sql.varchar2 table;

5 l status integer;

6 l cnt number := 0;



1242

Глава 16

7 l start number default dbms utility.get time;

8 begin

10 dbms sql.parse(l theCursor,

11 select object name from all objects,

12 dbms sql.native);

14 dbms sql.define array(l theCursor, 1, l columnValue, 100, 1);

15 l status := dbms sql.execute(l theCursor);

16 loop

17 l status := dbms sql.fetch rows(l theCursor);

18 dbms sql.column value(l theCursor,1,l columnValue);

20 l cnt := l status+l cnt;

21 exit when l status <> 10 0;

22 end loop;

2 3 dbms sql.close cursor(l theCursor);

24 dbms output.put line(L cnt rows processed);

2 5 dbms output.put line

26 (round((dbms utility.get time-l start)/100, 2 ) 11 seconds);

27 exception

28 when others then

2 9 dbms sql.close cursor(l theCursor);

30 raise;

31 end;

32 /

Procedure created.

scott@TKYTE816> set serveroutput on

scott@TKYTE816> exec native dynamic select 19695 rows processed

1.85 seconds

PL/SQL procedure successfully completed.

scott@TKYTE816> exec native dynamic select 19695 rows processed

1.86 seconds

PL/SQL procedure successfully completed.

scott@TKYTE816> exec dbms sql select 19695 rows processed 1.03 seconds

PL/SQL procedure successfully completed.

scott@TKYTE816> exec dbms sql select 19695 rows processed 1.07 seconds

PL/SQL procedure successfully completed.

Снова приходится выбирать между производительностью и простотой кода. Для обработки массивов средствами пакета DBMS SQL необходимо написать намного



1 ... 273 274 275 [ 276 ] 277 278 279 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика