|
Программирование >> Oracle
99 rows created Tine to INSERT: .04 seconds Time to ROLLBACK: .00 seconds Generated 12,728 bytes of redo 999 rows created Time to INSERT: .04 seconds Time to ROLLBACK: .01 seconds Generated 122,852 bytes of redo 9999 rows created Time to INSERT: . 94 seconds Time to ROLLBACK: .08 seconds Generated 1,170,112 bytes of redo 99999 rows created Time to INSERT: 8.08 seconds Time to ROLLBACK: 4.81 seconds Generated 11,842,168 bytes of redo PL/SQL procedure successfully completed. Это вполне можно было предсказать, поскольку при откате приходится физически отменять сделанные изменения. Как и при фиксации, необходимо выполнить ряд операций. Прежде чем добраться до оператора ROLLBACK, сервер уже многое сделал. Напомню, что б1ло сделано следующее: в области SGA сгенерированы записи сегмента отката; в области SGA сгенерированы измененные блоки данных; помещены в буфер журнала повторного выполнения в области SGA данные повторного выполнения для перечисленных выше изменений; в зависимости от размера этих трех фрагментов информации и прошедшего времени, часть их может уже быть сброшена на диск; установлены все необходимые блокировки. При откате: Отменяются все сделанные изменения. Это достигается путем считывания данных из сегмента отката и выполнения обратной операции. Если строка была вставлена, при откате она будет удалена. Если строка изменена, при откате будут восстановлены прежние значения столбцов. Если строка была удалена, при откате она будет снова вставлена. Снимаются все блокировки, удерживаемые сеансом, и все сеансы, ждавшие в очереди снятия этих блокировок, могут продолжить работу. При фиксации же просто сбрасываются на диск все данные, оставшиеся в буфере журнала повторного выполнения. По сравнению с откатом, действий при этом выполняется очень мало. Идея в том, что откатывать транзакцию не надо, если в этом нет крайней необходимости. Это влечет большие расходы ресурсов системы, поскольку сна- чала много времени уходит на выполнение изменений, а потом - на их отмену. Не делайте никаких изменений, если не собираетесь их фиксировать. Это кажется очевидным: естественно, никто ничего не делает, если не собирается результат фиксировать. Я, однако, неоднократно видел, как разработчики используют реальную таблицу в качестве временной, наполняя ее данными, а затем откатывая изменения. Ниже мы еще обсудим реальные временные таблицы и как избежать подобной проблемы. Какой объем данных повторного выполнения генерируется? Разработчикам может потребоваться определить объем генерируемых операциями данных повторного выполнения. Чем больше данных повторного выполнения генерируется, тем дольше будут выполняться операции и тем медленнее будет работать система в целом. Вы влияете не только на свой сеанс, но и на все сеансы. Управление данными повторного выполнения в базе данных осуществляется последовательно - рано или поздно все сеансы обращаются к процессу LGWR, чтобы он обработал их данные повторного выполнения и зафиксировал транзакцию. Чем больше ему надо сделать, тем медленнее будет работать система. Зная, сколько информации повторного выполнения генерируется, и проверяя несколько подходов к решению проблемы, можно найти наилучший вариант. Как было показано выше, определить объем генерируемой информации повторного выполнения достаточно просто. Я использовал представление динамической производительности VSMYSTAT, содержащее статистику только моего сеанса, и соединил его с представлением VSSTATNAME. Я выбрал из него значение статистического показателя redo size. Мне не пришлось угадывать имя этого показателя - его легко найти в представлении VSSTATNAME: ops$tkyte@DEV816> select from v$statname
14 rows selected. Теперь можно приступать к изучению способа определения объема генерируемгх транзакцией данных повторного выполнения. Достаточно легко оценить, сколько данных повторного выполнения будет сгенерировано, если известно, сколько данных будет изменено. Ниже я создаю таблицу, длина строки которой - около 2010 байт, плюс-минус несколько байт. Поскольку данные типа CHAR всегда имеют максимальный размер, в строке 2000 байт занимает столбец типа CHAR, 7 байт - столбец типа DATE, и три байта необходимо для представления числа - всего получается около 2010 байт, плюс некоторое количество байтов на представление строки: tkyte@TKYTE816> create table t (x int, у char(2000), z date); Table created. Рассмотрим, сколько данных повторного выполнения будет сгенерировано при вставке, затем - при изменении и, наконец, - при удалении одной, десяти и множества таких строк. Разберемся также, есть ли существенное различие между одновременным изменением строк и по одной, основываясь на объеме генерируемых данных повторного выполнения. Мы уже знаем, что изменение строк по одной выполняется медленнее, чем с помощью одного оператора UPDATE. Для измерения объема генерируемых данных повторного выполнения можно использовать средство AUTOTRACE утилиты SQL*Plus либо непосредственный запрос к представлениям V$MYSTAT/V$STATNAME, показывающий объем данных повторного выполнения сеанса: tkyte@TKYTE816> create or replace view redo size 2 as 3 select value 4 from v$mystat, v$statname 5 where v$mystat.statistic# = v$statname.statistic# 6 and v$statname.name = redo size; View created. Для операторов, трассируемых при установке AUTOTRACE (операторов INSERT, UPDATE и DELETE), мы будем использовать втдаваемую информацию. Для блоков PL/ SQL придется обращаться к представлениям V$MYSTAT/V$STATNAME, поскольку AUTOTRACE для них такую информацию генерировать не будет. Для оценки объема генерируемых данных повторного выполнения будем использовать созданную ранее таблицу Т со сравнительно постоянным размером строки 2010 байт, если все столбцы не могут иметь пустых значений. Будем выполнять различные операции и измерять объем сгенерированных при этом данных повторного выполнения. Вставим сначала одну строку, затем - десять строк с помощью одного оператора, затем - 200 строк также с помощью одного оператора и, наконец, 200 строк - по одной. Аналогичную проверку выполним для изменения и удаления строк. Ниже представлен код для этого примера. Вместо обычного копирования и вставки кода непосредственно из утилиты SQL*Plus, рассмотрим использованные операторы, а затем - таблицу итоговых результатов:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |