пережающее атрибутирование
Итак, вы обнаружили в файле расширенной трассировки SQL событие ожидания, занимающее много времени. Следующая задача состоит в том, чтобы определить, какую операцию приложения можно изменить с тем, чтобы уменьшить расход времени. Эта задача легко решается с помощью данных расширенной трассировки SQL. Необходимо сопоставить длительность каждого события WAIT #n первому вызову базы данных для курсора #n, который следует за данной строкой WAIT в файле трассировки. Я называю этот метод опережающим атрибутированием (forward attribution). Опережающее атрибутирование помогает безошибочно определить, какая из SQL-команд приложения отвечает за возникновение каждого периода ожидания. Как это ни удивительно, но опережающее атрибутирование работает для событий, исполняемых как внутри вызовов базы данных, так и между ними.
Для событий, исполняемых внутри вызовов базы данных, обоснование опережающего атрибутирования вполне понятно. Строки записываются в файл трассировки в момент завершения соответствующего действия, поэтому события ожидания, исполняемые определенным вызовом базы данных, появляются в потоке трассировки перед строкой вызова. Следующий отрывок кода (фрагмент примера 5.3), показывает, каким образом ядро Oracle выдает в файл трассировки строки для событий ожидания, исполняемых внутри вызова:
В этом примере события db file sequential read, которым соответствуют строки О и ©, были исполнены в контексте вызова FETCH, представленного в строке ©.
Для событий, исполняемых между вызовами базы данных, основание для применения опережающего атрибутирования не так очевидно. Следующий отрывок кода (фрагмент примера 5.4) помогает понять, как это работает. Из-за недостатков драйвера базы данных данное приложение дважды1 передает каждый вызов разбора в базу данных. Обратите внимание на две идентичных секции PARSING IN CURSOR, разделенные парой строк для событий to/from SQL*Net message:
Несмотря на то, что вызовы разбора были незатратными (два значения e=0 специально выделены в тексте), время отклика для всей пользовательской операции сильно увеличилось от огромного количества ненужных выполнений события SQL*Net message from client, на которые было потрачено в среднем 0,027 секунды на вызов. Общее влияние на время отклика составило несколько минут для пользовательской операции, которая в целом должна была занять менее 10 секунд (см. раздел «Ситуация 3: большая длительность события SQL*Net» в главе 12). Для того чтобы избавиться от исполнения событий SQL*Net, приведенных встроках О и ©, можно удалить вызов разбора, представленный встроке ©, которая следует за строками событий ожидания. В общем можно сказать, что вызов базы данных, «породивший» событие между вызовами, - это вызов базы данных, строка трассировки для которого следует за соответствующей строкой WAIT.
< Предыдущая | Следующая > |
---|