Очевидно, что исключение бесполезной работы в первую очередь сказывается на производительности приложения, выполнявшего ее прежде. Однако не все осознают огромный сопутствующий эффект от снижения нагрузки. Избавляясь от лишнего запроса к ресурсу, мы уменьшаем вероятность образования очереди из остальных пользователей к этому ресурсу. Понять дополнительную выгоду от снижения нагрузки довольно просто. Представьте себе программу, использующую процессор почти без перерывов в течение примерно 14 часов (профиль ресурсов такой программы приведен в примере 1.4). Пусть эффективность программы увеличилась настолько, что теперь ей требуется всего десять минут процессорного времени. (Такое улучшение обычно достигается работой с планом выполнения критических команд SQL.)
Понятно, почему будет доволен пользователь отчета, выполняемого теперь за десять минут вместо четырнадцати часов. Но представьте себе и радость остальных пользователей, которых тоже коснулось это улучшение. До улучшения пользователи, претендовавшие на время процессора, конкурировали с процессом, занимавшим его больше половины суток. Теперь же отчет претендует лишь на десять минут процессорного времени. Вероятность образования очереди на обслуживание процессором уменьшилась во много раз. При таком 14-часовом периоде выгода для системы сопоставима с эффектом от установки второго процессора.
В описанном случае преимущество от сокращения нагрузки на самом деле будет даже больше, чем от дополнительного процессора, т. к. второй процессор потребует от операционной системы дополнительных действий по диспетчеризации процессорного времени. Кроме того, уменьшение нагрузки обойдется дешевле, чем установка второго процессора.
Сопутствующая выгода от уменьшения нагрузки может быть ошеломляющей. Математически это обосновано в главе 9.
Как же исключить бесполезную нагрузку? Ответ зависит от уровня технологического стека. Понятие технологического стека системы было введено в главе 1, когда рассматривалось представление времени отклика пользовательской операции при помощи диаграммы последовательности. Технологический стек состоит из взаимодействующих друг с другом уровней, выступающих в роли поставщиков и потребителей, как показано на рис. 10.1. Отношения между ними просты.
Такое представление технологического стека помогает понять фундаментальную аксиому повышения производительности:
Почти всегда проблемы производительности бывают вызваны чрезмерными запросами к одному или нескольким ресурсам.
Практически в любом случае ухудшение производительности может быть устранено за счет уменьшения потребности в некотором ресурсе. Эта задача сокращения решается проходом «вверх» по технологическому стеку от перегруженного устройства. (Направление вверх в стеке соответствует направлению влево на диаграмме последовательности на рис. 10.1) Вопрос, которым следует задаться, занимаясь повышением производительности, звучит так:
Действительно ли оправдан столь высокий спрос на данный ресурс?
Рассмотрим профиль ресурсов, приведенный в примере 10.3. Без малого 97% времени отклика исследуемой пользовательской операции, составляющего 1,3 часа, расходуется на ожидание дискового ввода/ вывода. Согласно профилю ресурсов, возможны два решения:
Уменьшить количество вызовов, сделав так, чтобы оно не превышало 12165.
Уменьшить среднюю длительность вызова, сделав так, чтобы она не превышала 0,374109 секунды.
Учтите, что улучшение любого из этих показателей линейно сказывается на вкладе данного компонента в значение времени отклика. Если, например, уменьшить количество вызовов вдвое, то и длительность уменьшится вдвое. Аналогично, если сократить вдвое среднюю продолжительность вызова, длительность также уменьшится вдвое. Несмотря на то, что сокращение количества вызовов и их продолжительности одинаково сказывается на результирующем значении, обычно бывает значительно легче добиться существенного уменьшения количества вызовов, чем снизить их среднюю продолжительность. Я специально выбрал для этой книги такую последовательность столбцов профиля ресурсов, чтобы лучшее решение первым бросалось в глаза.
Пример 10.3. Во времени отклика выбранной пользовательской операции доминируют вызовы чтения подсистемы дискового ввода/вывода
Response Time Component
|
Duration
|
# Calls
|
Dur/Call
|
|
db file scattered read
|
4,551.0s
|
96.9%
|
12,165
|
0.374109s
|
CPU service
|
78.5s
|
1.7%
|
215
|
0.365023s
|
db file sequential read
|
64.9s
|
1.4%
|
684
|
0.094883s
|
SQL*Net message from client
|
0.1s
|
0.0%
|
68
|
0.001324s
|
log file sync
|
0.0s
|
0.0%
|
4
|
0.010000s
|
SQL*Net message to client
|
0.0s
|
0.0%
|
68
|
0.000000s
|
latch free
|
0.0s
|
0.0%
|
1
|
0.000000s
|
Total
|
4,694.5s
|
100.0%
|
Как исключить вызовы
Как уменьшить количество событий, выполняемых пользовательской операцией? Во-первых, выясните, что именно делает потребляемый ресурс. Что заставляет процесс Oracle, профиль которого приведен в примере 10.3, выполнять 12 165 вызовов многоблочного чтения? Затем выясните, можно ли обеспечить требуемую функциональность меньшим числом обращений к ресурсу. В главе 11 объясняется, как это сделать для нескольких часто встречающихся событий Oracle. Определите, можно ли ограничить потребность в перегруженном ресурсе, пройдя по всем уровням технологического стека. Например:
Многие аналитики полагают, что, увеличивая размер кэша буферов базы данных (т. е. выделяя больше памяти системе Oracle), они уменьшают вероятность обращения к дисковым устройствам, выполняемого вслед за просмотром памяти.
Однако поднявшись чуть выше по стеку, часто можно достичь гораздо лучших результатов, и не прибегая к увеличению объема памяти в системе. Оптимизируя план выполнения, следуя которому запрос извлекает строки из базы данных, часто удается избавиться даже от обращений к памяти.
Поднявшись по стеку еще выше, можно обнаружить еще более простые пути достижения результата. Например, может выясниться, что данная пользовательская операция может выполняться реже или не выполняться вообще (возможно, ее удастся чем-нибудь заменить), и это никак не скажется на ценности системы для бизнеса.
< Предыдущая | Следующая > |
---|