|
| ||||||||||||
| ||||||||||||
|
2004 г. Использование хранимых шаблонов (stored outlines) при настройке приложений с недоступным исходным кодом.Творошенко Сергей,
Oracle Certified Professional DBA,
В данной статье описывается один из многих аспектов использования хранимых шаблонов при настройке производительности приложений использующих СУБД Oracle. В частности, приводится пример их использования для настройки приложений, к исходному коду которых, группа сопровождения не имеет доступа. Приводимый пример был испытан в Oracle 9i release 2. Для выполнения SQL выражений использовалась приложение SQL*Plus. В практике сопровождения довольно часто приходится сталкиваться с задачей настройки производительности приложений, доступ к коду которых не представляется возможным. А производительность приложения сильно страдает из-за нескольких SQL выражений имеющих подсказки оптимизатору (optimizer hints) используя которые оптимизатор выбирает неоптимальный план выполнения SQL выражения. Особенно данная проблема имеет место при переходе организации на новые версии Oracle при использовании уже зарекомендовавших себя с хорошей стороны приложений, к которым все уже привыкли, однако вдруг начавших "жутко тормозить" на новой версии Oracle. Перехватив поток SQL выражений группа ИТ отдела определяет, что причина низкой производительности - подсказки, удалением которых можно добиться восстановления быстродействия. Однако сотрудники ИТ отдела не имеют доступа к исходному коду приложения и поэтому убрать "хинты" не представляется возможным. Решить подобные проблемы можно используя хранимые шаблоны. Русскоязычное описание использования хранимых шаблонов для стабилизации плана выполнения SQL выражений хорошо представлено в книге Тома Кайта "Oracle для профессионалов" (Thomas Kyte "Expert One on One: Oracle"), в переводе В. Кравчука, а так же на сайте (http://ln.com.ua/~openxs/projects/oracle/) автора перевода. Итак, перейдем к примеру. Начнем с постановки задачи. Допустим мы имеем SQL выражение содержащее подсказку /*+ RULE*/. Наша задача - избавиться от этой подсказки. Подготовим окружение. Создадим таблицу, составной индекс и соберем статистику. Таблица представляет собой некий словарь и содержит список словарей, каждый из которых, содержит некий список сущностей: dict_id - идентификатор словаряSQL> create table t1 (SQL> create index indx_t1Включим показ плана выполнения SQL выражений. SQL> set autotrace on explainСоздадим переменную привязки (bind variable), проинициализируем её и запустим наш оптимизируеммый запрос: SQL> var itemid numberПлан выполнения показывает полное сканирование таблицы (full table scan, FTS). Выполним тот же запрос, но "выключив" подсказку (уберем "+"): План выполнения показывает доступ к данным таблицы посредством индекса 'INDX_T1' . Доступ в пределах индекса осуществляется как INDEX SCIP SCAN ACCESS, впервые представленный в Oracle9i. Исходим из того, что набор данных в таблице таков, что, этот план намного лучше первого. К нему и будем стремится. Для дальнейшей работы нам потребуются следующие системные привилегии:
SQL> alter session set
create_stored_outlines = healthy_plans;В этом выражении HEALTHY_PLANS - это имя категории, с которой будут связаны наши шаблоны. Далее, выполним поочередно, два запроса. Первый - "проблемный", тот который мы собираемся оптимизировать(с подсказкой /*+ RULE*/). Второй, тот который мы прооптимизировали, "отключив" подсказку. Однако перед выполнением запросов нам необходимо отключить отображение планов выполнения запросов. Это нужно, чтобы Oracle перехватил, только наши два запроса (иначе будут перехвачены обращения к таблице PLAN_TABLE, содержащей планы выполнения):
На данном этапе важно отметить, что в отличие от Oracle8i, где сравнение SQL запросов с их аналогами в хранимых шаблонах происходит посимвольно, в Oracle9i оно не имеет столь жесткого критерия. Поэтому, скажем запрос: select /*+ rule*/ *с точки зрения использования хранимых шаблонов в Oracle 9i, аналогичен запросу: select /*+ RULE*/ * from t1 where
ItemID = :itemid;тогда, как в Oracle8i это было бы неверно. Итак, продолжим. Отключим автоматическое создание хранимых шаблонов: SQL> alter session set
create_stored_outlines = false;Смотрим, что получилось(для удобочитаемости, установим размер буфера отображения LONG полей равным 15): SQL> set long 15Полученным шаблонам придадим информативные имена: Подсказки хранимых шаблонов находятся в таблице ol$hints схемы OUTLN: SQL> select ol_name, hint#,
hint_text from outln.ol$hints
В вышеупомянутых русскоязычных источниках, описываются несколько приемов "обмана" CBO (Cost Based Optimizer), прибегнув к которым мы "заставим" CBO строить нужный нам план. В этой статье я предложу вам еще один подобный прием. Всё достаточно просто. Что нам нужно? Нам нужно чтобы при выполнении запроса с "хинтом" оптимизатор использовал подсказки из запроса с "отключенным хинтом". Итак, мы просто подменяем подсказки. Делаем это путем изменения имен хранимых шаблонов:
Ставший ненужным шаблон WITHOUT_PLUS - удаляем (фиксация предыдущих изменений нам не потребуется, т.к. SQL выражение DROP относится к числу изменяющих словарь данных Oracle (Data Definition Language, DDL), что вызывает неявную фиксацию предыдущей транзакции): SQL> drop outline WITHOUT_PLUS;Вот собственно и всё. Теперь можно проверить наш "проблемный" запрос. Для чистоты эксперимента, посмотрим еще раз на план нашего "проблемного" запроса: SQL> set autotrace on explainКак видим ничего не изменилось, всё тот же FTS. Активируем наш хранимый шаблон: SQL> alter session set
use_stored_outlines=HEALTHY_PLANS;И выполним еще раз всё тот же "проблемный" запрос: SQL> select /*+ rule*/ *
Цель достигнута. Изменив подобным образом все проблемные запросы и активировав соответствующую категорию полученных хранимых шаблонов, можно добиться прежней производительности приложения. "А что же будет, если мы таким образом подменим план, который был сделан на основе совершенно другой таблицы, либо, скажем, удалим индекс таблицы в существующем примере?" - задаст вопрос проникшийся идеей читатель. Ответ прост - CBO выдаст план, так, как будто бы хранимого шаблона и нет вовсе. Проводя исследования в данном направлении я наблюдал интересный момент. Вот что я сделал. Я удалил индекс в таблице t1. Проверил реакцию CBO, он проигнорировал хранимый шаблон (как я уже говорил). Вновь создал индекс с тем же именем и на те же поля. И вот тут самое интерестное! Т. к. я не пересобирал статистику на таблицу после создания индекса, то выполнение запроса "без плюсика", привело к FTS, а выполнение нашего "проблемного" запроса, показало прекрасный план, взятый CBO из нашего шаблона. Вот такие дела :). Не забывайте собирать статистику! |
|
CITForum © 1997–2025