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

1 ... 62 63 64 [ 65 ] 66 67 68 ... 469


20 21 22 23 24 25 26

28 29 30 31 32 33 34 35 36 37 38 39

40 41 redo redo redo

(x.object id, x.object name, x.created);

commit; end loop; report;

select value into l redo size from redo size;

for x in (select rowid rid from t)

loop

update t set у = lower (у) where rowid = x.rid; commit; end loop; report;

select value into l redo size from redo size;

for x in (select rowid rid from t)

loop

delete from t where rowid = x.rid; commit; end loop; report; end; /

size = 530396 rows = 200 2,652.0 bytes/row size = 956660 rows = 200 4,783.3 bytes/row size = 537132 rows = 200 2,685.7 bytes/row

PL/SQL procedure successfully completed.

Как видите, фиксация кажждой строки заметно увеличила объем генерируемых дан-н1х повторного выполнения (итоговые результаты представлены в следующей таблице). Есть и другие причины, связанные с производительностью, объясняющие, почему не стоит фиксировать кажждую измененную строку (или группу строк). Мы видели непосредственное доказательство этого в примере выше, где фиксация каждой строки требует в три раза больше времени, чем фиксация после завершения транзакции. Дополнительные затраты времени связаны с обращением к ядру сервера, установкой дополнительных защелок и возникновением конфликтов при доступе к общим ресурсам при выполнении каждого оператора. Итак, если что-то можно сделать с помощью одного оператора SQL - делайте это именно так. Кроме того, фиксируйте транзакцию, только когда она закончена, не раньше.

Операция

Количество

Общий объем

Общий объем

% увеличения

затронутых

данн1х

строк

повторного

повторного

выполнения

выполнения

(без фиксации)

(с фиксацией)

Вставка 200 строк

442784

530396

Изменение 200 строк

849600

956660

Удаление 200 строк

469152

537132



Представленный выше метод пригодится и для оценки побочных эффектов различ-н1х вариантов работы. Один из часто возникающих вопросов связан с триггерами. Помимо того, что в триггере BEFORE можно изменять указанные значения строки, есть ли еще какие-то особенности применения триггеров? Как оказалось, есть. Триггер BEFORE создает дополнительные данные повторного выполнения, даже не изменив ни одного значения в строке. Этот вопрос достоин отдельного изучения, и с помощью представленных выше методов можно убедиться, что:

триггер BEFORE или AFTER не влияет на объем данных повторного выполнения для операторов DELETE;

оператор INSERT генерирует дополнительно одинаковый объем данных повторного выполнения при наличии триггера BEFORE или AFTER;

на объем данных повторного выполнения, генерируемых оператором UPDATE, влияет только наличие триггера BEFORE - триггер AFTER не генерирует дополнительных данных;

размер строки влияет на объем дополнительно генерируемых данных повторного выполнения для операторов INSERT, но не для операторов UPDATE.

Используем таблицу Т из предгдущего примера: create table t (x int, у char(N), z date);

но создадим несколько ее версий с разными значениями N. В данном случае мы используем значения N = 30, 100, 500, 1000 и 2000 для получения строк разного размера. Я использовал простую таблицу для регистрации результатов нескольких экспериментов:

create table log (what varchar2(15), - будет иметь значения по trigger, after

- или before

op varchar2(10), - будет иметь значения insert, update или

- delete

rowsize int, - будет содержать размер столбца Y

redo size int, - будет содержать объем сгенерированных

- данных повторного выполнения

rowcnt int) ; - будет содержать количество обработанных

- строк

Выполнив тест с различными размерами столбца Y, проанализируем результаты. Я использую следующую хранимую процедуру для генерации транзакций и записи объема сгенерированных данных повторного выполнения. Подпроцедура REPORT - это локальная процедура (видимая только в процедуре DO WORK), выдающая на экран информацию о происходящем и записывающая полученные результаты в таблицу LOG. Основное тело процедуры выполняет проверяемые транзакции. Все начинается с запоминания текущего объема данных повторного выполнения в текущем сеансе, выполнения определенных действий, а затем генерируется отчет:

tkyte@TKYTE816> create or replace procedure do work (p what in varchar2)

2 as

3 l redo size number;

4 1 cnt number := 200;



6 procedure report(l op in varchar2)

7 is

8 begin

9 select value-l redo size into l redo size from redo size;

10 dbms output.put line(l op redo size = l redo size

11 rows = l cnt

12 to char(l redo size/l cnt, 99,999.9)

13 bytes/row);

14 insert into log

15 select p what, l op, data length, l redo size, l cnt

16 from user tab columns

17 where table name = T

18 and column name = У;

19 end;

20 begin

21 select value into l redo size from redo size;

22 insert into t

23 select object id, object name, created

24 from all objects

25 where rownum <= l cnt;

26 l cnt := sql%rowcount;

27 commit;

28 report(insert); 29

30 select value into l redo size from redo size;

31 update t set y=lower(y);

32 l cnt := sql%rowcount;

33 commit;

34 report(update); 35

36 select value into l redo size from redo size;

37 delete from t;

38 l cnt := sql%rowcount;

39 commit;

40 report(delete);

41 end;

42 /

Procedure created.

Теперь, когда все готово, я удалю и создам таблицу Т, изменяя размер столбца Y. Затем выполню следующий код для тестирования различнгх сценариев (без триггеров, с триггером BEFORE и с триггером AER):

tkyte@TKYTE816> truncate table t; Table truncated.

tkyte@TKYTE816> exec do work(no trigger); insert redo size = 443280 rows = 200 2,216.4 bytes/row update redo size = 853968 rows = 200 4,269.8 bytes/row delete redo size = 473620 rows - 200 2,368.1 bytes/row



1 ... 62 63 64 [ 65 ] 66 67 68 ... 469

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