|
Программирование >> Oracle
set autotrace traceonly statistics insert into t values (1, user, sysdate); insert into t select object id, object name, created from all objects where rownum <= 10; insert into t select object id, object name, created from all objects where rownum <= 200 declare l redo size number; l cnt number := 0; begin select value into l redo size from redo size; for x in (select * from all objects where rownum <= 200) loop insert into t values (x.object id, x.object name, x.created); l cnt := l cnt+l; end loop; select value-l redo size into l redo size from redo size; dbms output.put line(redo size = l redo size rows = l cnt); end; / Этот фрагмент кода выполняет описанные операторы вставки - 1, 10, 200 строк за раз, затем - 200 отдельных операторов INSERT. Выполним изменения: update t set y=lower(y) where rownum = 1; update t set y=lower(y) where rownum <= 10; update t set y=lower(y) where rownum <= 200; declare l redo size number; l cnt number := 0; begin select value into l redo size from redo size; for x in (select rowid r from t where rownum <= 200) loop update t set y=lower(y) where rowid = x.r; l cnt := l cnt+l; end loop; select value-l redo size into I redo size from redo size; dbms output.put Iine(redo size = l redo size rows = l cnt); end; и, наконец, удаления: delete from t where rownum = 1; delete from t where rownum <= 10; delete from t where rowjnum <= 200; declare l redo size number; l cnt number := 0; begin select value into l redo size from redo size; for x in (select rowid r from t) loop delete from t where rowid = x.r; l cnt := l cnt+l; end loop; select value-l redo size into l redo size from redo size; dbms output.put line(redo size = l redo size rows = l cnt); end; Вот результаты эксперимента:
Интересно отметить, что при изменении 200 строк с помощью одного оператора и по одной генерируется одинаковый объем данных повторного выполнения. Это верно и для операторов DELETE: один или 200 операторов - результат одинаков. Операторы вставки ведут себя немного иначе. При вставке строк по одной генерируется немого больше данных повторного выполнения, что вполне логично, если учесть, что при вставке по одной строке данные в блоках организуются немного не так, как при множественной вставке (при этом необходимо выполнить немного больше работы). Как видите, объем генерируемых данных повторного выполнения зависит от объема изменяемых данных. При вставке строк размером 2000 байт генерируется немногим более 2000 байт для каждой строки. При выполнении оператора UPDATE объем генерируемых данных повторного выполнения удваивается (если помните, в журнал записываются данные и изменения в сегменте отката, так что это вполне логично). Оператор DELETE генерирует данные почти такого же объема, что и оператор INSERT. В сегменте отката записана вся строка, и это отражается в журнале, но записываются еще и изменение в блоке, что и объясняет небольшие расхождения. Поэтому, если известен объем изменяемых данных и то, как они будут изменяться, определить объем даннгх повторного выполнения легко. Этот пример не показывает, что построчная обработка так же эффективна, как и обработка множества строк. Он показывает только, что при этом генерируется одинаковый объем данных повторного выполнения. В предыдущих главах было продемонстрировано, что процедурная обработка строк никогда не бывает настолько эффективной, как обработка множеств. Кроме того, если выполнять в цикле операторы COMMIT, как делают многие исходя из ошибочного предположения, что этим экономят ресурсы, проблема только усложняется. Теперь, зная, как оценить объем генерируемых данных повторного выполнения, можно четко показать последствия этой неудачной идеи. Используем ту же схему, что и в предыдущем примере, и посмотрим, что произойдет при выполнении оператора COMMIT в цикле: tkyte@TKYTE816> declare 2 l redo size number; 3 l cnt number := 20 0; 4 procedure report 5 is 6 begin 7 select value-l redo size into l redo size from redo size; 8 dbms output.put line(redo size = l redo size 9 rows = l cnt 10 to char(l redo size/l cnt, 99,999.9} 11 bytes/row); 12 end; 13 begin 14 select value into l redo size from redo size; 15 fox x in (select object id, object name, created 16 from all objects 17 where rownum <= l cnt) 18 loop 19 insert into t values
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.002
При копировании материалов приветствуются ссылки. |