|
|
|||||||||||||||||||||||||||||
|
Какие планы у Oracle?Владимир Пржиялковский
СодержаниеВсе SQL-запросы, поступающие в СУБД Oracle , как известно, и как это устроено и в других системах, "проживают" в общем случае одинаковые стадии своего жизненного цикла: (1) синтаксического анализа; Не стоит и говорить, сколь много зависит от стадии 2 выработки алгоритма выполнения запроса: если он дает правильный результат, но составлен нерационально, время реакции СУБД на запрос может возрасти против более оптимального в десятки, а то и тысячи раз. За выработку алгоритма для выполнения запроса в Oracle отвечает часть СУБД, называемая оптимизатором . Сам алгоритм по терминологии Oracle носит название плана [обработки запроса]. Если точнее, то оптимизаторов в Oracle два: т.н. "Rule based" (RBO) и "Cost based" (CBO). Каждый запрос обрабатываться одним из этих оптимизаторов, за исключением случаев с подзапросами, для которых вид оптимизатора можно указывать индивидуально, безотносительно к оптимизатору для внешнего запроса. Оптимизатор - программа, написанная людьми из общих предположений, а все БД по определению конкретны, и поэтому вовсе не факт, что планы, предлагаемые оптимизатором, всегда безупречны. Таким образом, одной из первейших забот разработчика ИС и АБД становится контроль качества предлагаемых оптимизатором планов с целью попытаться как-нибудь изменить наименее приемлемые планы в лучшую сторону. (В жизни часто это контроль поневоле, после обнаружения неприемлемой медленности запросов).
План, предлагаемый оптимизатором в Oracle, конечно же, зависит от текста запроса, но отнюдь не только от него, в особенности в CBO. Последнее обстоятельство нередко ставит начинающего пользователя в тупик. Поскольку цена проблемы может оказаться велика, разобраться в том, какие факторы, помимо исходного текста, влияют на работу оптимизатора в каждом конкретном случае немаловажно. Ниже эти факторы перечисляются с короткими пояснениями. Факторы влияния на выбор плана RBO Исторически RBO - предшественник оптимизатора CBO, но начиная с версии 8 он отошел на второй план, хотя продолжает поддерживаться и даже понемногу развиваться. Его главной особенностью является попытка вырабатывать план, более предпочтительный с точки зрения "более эффективного" доступа к данным. "Эффективность" определяется просто: по фиксированной таблице разновидностей доступа к данным, упорядоченных по критерию предпочтительности (от выхода на строку по физическому адресу до полного сканирования). Логически работу RBO можно представить так: сначала он составляет полный перечень всех возможных вариантов (планов) обработки запроса, потом вычисляет для каждого варианта вес и выбирает наиболее "легкий". (Разумеется, что фактически RBO так безумно не поступает ввиду несметного числа вариантов в общем случае, но фактическая техника - это попытка приблизиться к результату, даваемому именно такой логикой). На выработку плана конкретного запроса этим оптимизатором влияют следующие факторы:
Небольшие замечания по поводу этих факторов. (1) В новых версиях СУБД оптимизатор может подправляться: разработчики могут пытаться устранить некоторые замеченные ошибки или добавить новые свойства поведения. Внутренняя логика RBO относительно проста, поэтому часто разница может свестись лишь к изменению таблицы предпочтительности доступа: в версии 9.0 эта таблица состоит из 20 позиций, а в некоторых более ранних была короче. Факторы влияния на выбор плана CBO В отличие от RBO, CBO пытается оптимизировать затраты ресурсов компьютера на выполнение каждого отдельного запроса. Можно посочувствовать разработчикам Oracle: задача недостижимая! Действительно, существует по крайней мере три таких ресурса: процессорное время, расход оперативной памяти и число обращений к диску. Многокритериальная оптимизация не имеет общего решения, и поэтому CBO почти всегда будет вам предлагать какой-то компромисс. Вовсе не факт, что этот компромисс вас устроит, и тогда придется использовать "факторы влияния" в своих корыстных целях (есть, правда, и более жесткие средства). CBO - программа, намного более сложная, чем RBO, и факторов влияния на выбор этой программой плана существенно больше. Вот эти факторы:
Небольшие замечания по поводу этих факторов. (1) В общем, аналогично RBO, но можно привести пару уточнений. Так, в версии СУБД 8.0.4 было устранено очень много прежних ошибок. В версии 9.0 сделано существенное улучшение работы с переменными привязки в тексте запроса: если прежде они до выработки плана не оценивались, то теперь оптимизатор сначала узнает их реальные значения, а потом предложит план. Так планы в вашей программе могли "сами поменяться". В целом и эксперты, и представители Oracle рекомендуют работать с CBO, а не с RBO. В целом, опять-таки, CBO достаточно надежен и ведет себя разумно. Простая иллюстрация тому - пример отбора пяти высокооплачиваемых сотрудников (типовая задача). Вот три ("с половиной") разных способа, которые работают в версии 8.1.7:
SELECT ename, -sal sal
SELECT *
SELECT * FROM
SELECT * FROM Читателям старых номеров журнала "Мир Oracle" напомню, что вариант А взят оттуда. Обратите внимание, что порядок сотрудников в выдаваемых списках при прогоне запросов разный; это нормально. Вариант В' - это вынужденная уловка, так как замена SELECT * на SELECT ename, sal (как хотелось бы) во внешнем SELECT варианта В неожиданно резко портит результат, что наводит на мысль об отсутствии знаний о столбовой дороге к безупречному коду у разработчиков Oracle. А вот соответствующие планы:
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=16 Bytes=320)
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=16 Bytes=320)
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=16 Bytes=528)
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=16 Bytes=528) Видно, что все планы разные ("фактор синтаксиса"), но все они имеют приятную для нас общность: - во всех используется STOPKEY, то есть избегается полный перебор (По поводу стоимостей запроса, указанных параметром Cost не следует быть чересчур придирчивым: во-первых, это лишь оценки оптимизатора, а не реальная статистика. За точной реальной статистикой затрат ресурсов придется обратиться к SQL Trace. Во-вторых, запросы сделаны по небольшой табличке демонстрационного примера в схеме SCOTT). Тем не менее, полностью доверяться мудрости CBO сегодня нельзя. Так, еще один вариант запроса по "первой пятерке"
SELECT ename, sal FROM даст такой план:
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=16 Bytes=528) STOPKEY пропал. Пример Г дает еще один урок: похоже, что определяющую роль для этого плана играет синтаксис, и попытка "поиграться" прочими факторами ничего нам не даст. Кроме, может быть, "фактора версии СУБД": для сравнения, тот же запрос в версии 9.2 получит несколько иной план:
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=14 Bytes=462) Обратите также внимание на изменения в оценках стоимости выполняемых шагов. В первой строке Card=14, видимо, недоработка разработчиков, так как для А, Б и В/В' версия 9.2 дает более точную оценку: Card=5 (Bytes в 9.2 тоже оценивается точнее). Post Scriptum. Новые для Oracle аналитические функции, сами по себе надежные, в некоторых технических деталях недостаточно четко описаны. А решение А привязано к побочному эффекту. Поэтому для конкретной задачи первой (последней) пятерки я бы рекомендовал следующие надежные решения: Б и Г. Ссылки по теме
|
|