Базы данных Oracle - статьи

         

в документации возможностью, которую мог


В Oracle версии 6 трассировка SQL-операторов стала базовой, описанной в документации возможностью, которую мог использовать каждый. В версии 6 Oracle представил операторы, которые работают и в версиях 7, 8, 9 и 10:

alter session set sql_trace=true ... alter session set sql_trace=false

Установка sql_trace была существенным шагом вперед для всех занимающихся анализом производительности приложений. Она позволила получить последовательность SQL-операторов, выполненных приложением, а также оценить нагрузку на СУБД, которую они представляли. Необработанные результаты трассировки (см. ранее) выглядели весьма непонятно, но это не имело большого значения, поскольку корпорация Oracle предоставила средство обработки трассировочных файлов tkprof, которое выдавало информацию во вполне понятном виде. (См. ранее. получен на версии 9.2.0.1, но, хотя с версии 6 формат представления результатов немного изменился, по сути, выдаются те же данные.)

Теперь на лучших курсах по "настройке" Oracle, помимо использования магических коэффициентов (вроде процента попадания в буферный кеш), слушателей обучали интерпретации результатов tkprof. При этом предалаглись следующие весьма простые правила:

  • Надо уменьшать значения в столбце count. Т.е. надо сокращать количество обращений к СУБД. Наиболее действеным способом для этого будет изменение кода приложения.


  • Надо уменьшать значения в столбцах query и current (они получаются по значениям полей cr и cu в трассировочных файлах, соответственно). Другими словами, надо читать из буферного кеша как можно меньше блоков. Иногда для этого достаточно создать или удалить индекс, а иногда - переписать по-другому SQL-оператор.


  • Если сумма query + current сведена к минимуму, а в столбце disk - ненулевое значение, рекомендовалось увеличить буферный кеш. Т.е. избавиться от лишних "физических" чтений, но только после того, как избавились от всех лишних логических.


  • Конечно, к таким рекомендациям пришли не сразу. Многие советовали сначала сводить к нулю значения в столбце disk. Сейчас многим уже известно, что при этом мы провоцируем серьезную проблему производительности: SQL-оператор может находить все необходимые блоки данных в буферном кеше, но при этом быть ужасно неэффективным. Но во времена версии 6 об этом еще не задумывались.



    Когда проблема была связана с неэффективными SQL-операторами, неудачной структурой схемы, недостающими индексами, избыточным анализом или неиспользованием возможностей сервера Oracle по обработке множеств, результаты трассировки позволяли выявить проблему. Но для решения некоторых проблем информации в трассировочных файлах было явно недостаточно. Стандартной трассировочной информации недостаточно, когда реальное время выполнения SQL-операторов существенно превосходит процессорное. Например, запрос выполняется 23 секунды, но процессорного времени для него потребовалось лишь 0,17. Что вы можете сказать по остальные 22,83 секунды? При использовании стандартной трассировочной информации ничего определенного сказать нельзя.

    Конечно, незнание не мешает выдвигать гипотезы. Наиболее популярной гипотезой, "объясняющей" все проблемы производительности в те времена был ввод-вывод с диска. Это предположение было верно в некоторых случаях, но лишь в некоторых. Что, если проблема не связана с чрезмерной нагрузкой на процессор и с вводом-выводом с диска?

    содержит пример, иллюстрирующий проблему. Простой оператор UPDATE изменяет строку по первичному ключу. Он затронул только одну строку (r=1), но выполнялся 10,56 секунды (e=1056). Куда ушло столько времени? Понятно, что не на вычисления, поскольку процессорного времени ушло всего около 0,02 секунды (c=2). Дисковый ввод-вывод тоже не при чем, поскольку, судя по данным трассировки, ядро при изменении не выполнило ни одной операции чтения ОС (p=0). Как узнать, почему это изменение выполнялось более 10 секунд?

    Листинг 3. Трассировка уровня 1, показывающая, что общее время выполнения значительно превосходит процессорное

    ===================== PARSING IN CURSOR #1 len=31 dep=0 uid=73 oct=6 lid=73 tim=27139911 hv=1169598682 ad ='68f56dc8' update c set v1='y' where key=1 END OF STMT PARSE #1:c=0,e=902,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=4,tim=27139911 EXEC #1:c=2,e=1056,p=0,cr=3,cu=3,mis=0,r=1,dep=0,og=4,tim=27140969


    Содержание раздела