Скачиваний:
82
Добавлен:
02.05.2014
Размер:
2.28 Mб
Скачать

17.3. Оптимизация запросов

Рассмотрим четыре стадии процесса оптимизации запросов, который схематически представлен на рис. 17.1.

  1. Преобразование запроса во внутреннюю форму.

  2. Преобразование запроса в каноническую форму.

  3. Выбор потенциальных низкоуровневых процедур.

  4. Генерация различных вариантов планов вычисления запроса и выбор плана с ми- нимальными затратами.

Перейдем к подробному рассмотрению каждой стадии процесса оптимизации.

Процессор языка Сканирование, манипулирования обработка представлений, данными трансляция

Выражение реляционной алгебры

Преобразование выражения, оценка стоимости выполнения и т.д.

Оптимизированный код

Выполнение

Стадия 1. Преобразование запроса во внутреннюю форму

На этой стадии выполняется преобразование запроса в некоторое внутреннее пред- ставление, более удобное для машинных манипуляций. В результате из рассмотрения полностью исключаются конструкции сугубо внешнего уровня (например, разнообраз- ные варианты конкретного синтаксиса используемого языка запросов) и готовится почва для последующих стадий оптимизации.

Замечание. Обработка представлений (т.е. процесс замены ссылок на представления выражениями, определяющими соответствующие представления) также выполняется на этом этапе.

Возникает очевидный вопрос: "Какое формальное представление должно использо- ваться для внутреннего представления запроса?". Независимо от того, какой именно ва- риант формального представления будет выбран, он должен быть достаточно полным, чтобы допускать представление любых запросов, которые могут быть определены на внешнем языке системы. Кроме того, выбранный способ формального представления должен быть нейтральным, насколько это возможно, в том смысле, что он не должен за- ранее предопределять последующих оптимизационных решений. Чаще всего для внут- реннего представления запросов используется та или иная модификация абстрактного синтаксического дерева, которое в этом случае называется деревом запроса. Напри- мер, на рис. 17.2 показано дерево для запроса, рассматривавшегося выше в этой же главе ("Определить имена поставщиков детали с номером 'Р2'").

Окончательный результат

т

Проекция по атрибуту SNAME Т

Выборка кортежей, в которых Pi =

т

т

S

Соединение по атрибуту St Т 1

SP S

'Р2'

Рис. 17.2. Дерево реализации запроса "Определить имена поставщиков детали с но- мером 'Р2'"

Однако для наших целей удобнее всего будет предположить, что для внутреннего представления запросов используется один из тех формальных методов, с которыми мы уже знакомы: реляционная алгебра или реляционное исчисление. В этом случае дерево запроса, подобное представленному на рис. 17.2, можно будет рассматривать просто как альтернативный схематический вариант представления некоторого выражения, записан- ного в нотации одного из двух предложенных выше формальных методов (реляционная алгебра или реляционное исчисление). Предположим, что выбранный формальный метод — реляционная алгебра. С этого момента будем считать, что внутренним пред- ставлением дерева запроса, показанного на рис. 17.2, является следующее алгебраиче- ское выражение.

( ( SP JOIN S } WHERE Pi = Pi ( 'P2' ) ) { SNAME }

Стадия 2. Преобразование запроса в каноническую форму

' Следует заметить, что язык SQL исключительно предрасположен к этому (см. упр. 7.12 в главе 7, а также [4.18]). Другие языки (напршиер, языки реляционной алгебры или исчисления) обычно не позволяют создать такое же количество эквивалентных по результату выражений. Эта излишняя "гибкость " языка SQL на самом деле усложняет жизнь разработчикам (а не поль- зователям), поскольку существенно усложняет алгоритм оптимизатора.

На этой стадии оптимизатор выполняет несколько операций оптимизации, которые "гарантированно являются хорошими" независимо от реальных значений данных и су- ществующих путей доступа к ним. Суть в том, что обычно реляционные языки позволя- ют сформулировать любые запросы (за исключением разве что простейших) нескольки- ми разными (по крайней мере, внешне) способами. Например, даже простой запрос "Определить имена поставщиков детали с номером 'Р2'" на языке SQL может быть за- писан буквально десятками способов1, не считая таких тривиальных вариантов, как за- мена А = В на В = А или р AND q на q AND р. Производительность вычисления запроса не должна зависеть от формы записи запроса, которую выбрал пользователь. Поэтому следующий этап в обработке запроса — преобразование его внутреннего представления в некоторую эквивалентную каноническую форму (см. ниже). Назначением данного преобразования является исключение внешних различий в эквивалентных представлени- ях запроса и, что более важно, поиск представления запроса, в некотором смысле более эффективного по сравнению с исходным представлением.

Замечание о канонической форме. Понятие канонической формы является централь- ным во многих разделах математики и связанных с ней дисциплинах. Каноническая форма может быть определена следующим образом. Пусть Q— множество объектов (запросов), и пусть существует понятие об их эквивалентности (а именно: запросы ql и q2 эквивалентны тогда и только тогда, когда дают идентичные результаты). Тогда под- множество С множества Q является подмножеством канонических форм для запросов из множества Q в смысле определенной выше эквивалентности тогда и только тогда, ко- гда каждому объекту q из множества Q соответствует только один объект с из множества С. В этом случае говорят, что объект с является канонической формой объекта q. Все "интересующие" свойства, которыми обладает объект q, также присущи объекту с. По- этому, чтобы доказать различные "интересующие" результаты, достаточно изучить ме- нее мощное множество объектов С, а не более мощное множество Q.

Вернемся к основной теме обсуждения. Чтобы преобразовать результаты выполнения стадии 1 в некоторую эквивалентную, но более эффективную форму, оптимизатор ис- пользует определенные и хорошо известные правила преобразования, или законы. Ниже приведен пример такого правила. Здесь выражение

( A JOIN В ) WHERE <выборка из> А

может быть преобразовано в эквивалентное, но более эффективное выражение ( A WHERE <выборка из> А ) JOIN В

Подобное преобразование кратко рассматривалось в разделе 6.6. Кроме того, оно бы- ло приведено несколько выше, при обсуждении примера в разделе 17.2, который ясно продемонстрировал, зачем нужны подобные преобразования. Многие другие правила преобразования описываются ниже, в разделе 17.4.

Стадия 3. Выбор потенциальных низкоуровневых процедур

После преобразования внутренней формы запроса в более подходящую (каноническую) форму оптимизатор должен решить, как следует выполнять запрос, представленный в этой канонической форме. На данной стадии принимаются во внима- ние наличие индексов и других путей доступа, статистическое распределение сущест- вующих значений данных, физическая кластеризация хранимых данных и т.п. Обратите внимание, что на стадиях 1 и 2 этим аспектам совсем не уделялось внимания.

Основная стратегия состоит в том, чтобы рассматривать выражение запроса как се- рию низкоуровневых операций (соединения, выборки и т.п.), которые в определенной степени зависят одна от другой. Ниже приведен пример такой зависимости. При про- граммной реализации выполнения проекции обычно требуется, чтобы считываемые кор- тежи следовали в определенном порядке; это позволит исключить дублирующиеся ре- зультирующие кортежи. В свою очередь, это означает, что выполняемая непосредствен- но перед проекцией операция должна выдавать выходные кортежи именно в такой, тре- буемой последовательности.

Для каждой низкоуровневой операции (а также, возможно, для нескольких часто встречающихся комбинаций подобных операций) оптимизатор имеет набор низкоуров- невых процедур реализации. Например, существует набор процедур для реализации операции выборки: по условию равенства определенному значению потенциального

ключа; на основе индексированного атрибута, по которому выполняется выборка; на ос- нове хешированного атрибута и т.д. Примеры таких процедур приведены ниже, в разде- ле 17.7 (см. также [17.8]—[ 17.14]).

С каждой процедурой связана и параметризованная формула стоимости, позволяю- щая оценить стоимость выполнения процедуры (т.е. уровень затрат, требуемых для ее выполнения). Чаще всего стоимость определяется на основе подсчета количества необ- ходимых дисковых операций ввода-вывода, но некоторые системы учитывают также время использования процессора и другие факторы. Эти формулы стоимости применя- ются на стадии 4. В [17.8]—[ 17.14] обсуждаются и анализируются формулы стоимости для различных процедур реализации при разных исходных предположениях.

Далее, используя сохраняемую в каталоге информацию о состоянии базы данных (существующие индексы, текущую кардинальность переменных-отношений и т.п.) и све- дения о взаимозависимостях, упоминавшихся выше, оптимизатор выбирает одну или не- сколько процедур-кандидатов для каждой низкоуровневой операции в запросе. Этот процесс обычно называют выбором пути доступа (см. также [17.34], [17.35]).

Замечание. Следует отметить, что в [17.34], [17.35] приведенный термин использует- ся для ссылки на определенные в данной главе стадии 3 и 4, а не только на стадию 3. Действительно, на практике очень трудно разграничить, где заканчивается одна стадия и начинается другая: просто стадия 3 плавно переходит в стадию 4.

Стадия 4. Генерация различных вариантов планов вычисления запроса и выбор плана с минимальными затратами

На последней стадии процесса оптимизации создается набор потенциальных планов запроса, после чего следует выбор лучшего (т.е. наименее дорогого) плана выполнения за- проса. Каждый план выполнения строится как комбинация некоторого набора процедур реализации, причем каждой низкоуровневой операции в запросе соответствует одна проце- дура. Заметьте, что обычно для поступившего запроса вырабатывается множество планов выполнения запроса (возможно, даже слишком много). На практике, вероятно, не стоит ге- нерировать все возможные планы запроса, так как одни из них могут быть комбинаторны- ми версиями других планов выполнения этого же запроса и сам процесс выбора наиболее дешевого плана может стать чрезмерно дорогостоящим. При выборе плана с наименьшей стоимостью рекомендуется (возможно, даже необходимо) руководствоваться некоторыми эвристическими правилами, позволяющими ограничить количество анализируемых планов запросов разумными пределами [17.55]. Практику ограничения количества запросов ра- зумными пределами иначе называют сокращением пространства поиска, поскольку ее можно рассматривать и как уменьшение диапазона ("пространства") анализируемых опти- мизатором вариантов ("поиск") до контролируемых пределов.

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

зультатов выполнения, оптимизатор должен суметь оценить размер этих результатов и использовать полученные значения при вычислении формул стоимости. К сожалению, размеры промежуточных наборов данных сильно зависит от конкретных значений хра- нимых данных, поэтому точная оценка стоимости может оказаться достаточно сложной проблемой. В [17.3], [17.4] обсуждаются некоторые подходы к решению этой проблемы и приводятся ссылки на другие направления исследований.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]