вторник, 20 мая 2008 г.

Трансформации в оптимизаторе

По мотивам статьи

Трансформации оптимизатора бывают heuristic и cost-based (появился в Oracle 10g). При трансформации Oracle старается уменьшить количество блоков запросов (через merge), уменишить количество передающихся из шага в шаг данных (применение фильтрации на ранних стадиях, правильный порядок соединений), убирание ненужных операций.

Типы трансформаций.

1.Subquery unnesting.
В 9-м оракле делалось всегда. Оптимизатор может сделать unnest многих запросов за исключением запросов:
  • связанных с non-parents
  • связанных по OR
  • некоторые запросы ALL с несколькими условиями связи с NULL значениями

Существует 2 типа unnest:
  • в inline-view
  • merge с родительским запросом
Конвертация в родительский запрос дает возможность выбирать соединение между таблицами.

2. Join elimination
Убирает таблицу из родительского запроса, если она нигде не используется, например
SELECT emp.name, emp.salary
FROM emp, dep
WHERE emp.dep_id = dep.dep_id

преобразуется в запрос
SELECT emp.name, emp.salary
FROM emp

если в таблице создан foreign key и есть условие not null на колонке (или в запросе).

3. Filter predicate movearound
Предикат может передаваться в подзапрос, идти в родительский запрос, в соседний запрос.

4. Group pruning
Убирает лишние группировки, если они не используются во внешних запросах

5. Group by и Distinct view merging

Мержит во внешний запрос блок, содержащий group by или distinct. Такое преобразование позволяет не только использовать различные пути соединения таблиц, но и отложить группировку, что может уменьшить время выполнения запроса через уменьшение количества строк для аггрегации. С другой стороны при помощи агрегации и последующей фильтрации можно уменьшить количество строк для соединения, поэтому решение о такой трансформации COST BASED.

6. Join predicate pushdown
Позволяет соединяться между view и остальным запросом при помощи индексов и nested loops. Может применяться к mergable (group by, distinct) и nonmergable (union all, union, semi, anti, outerjoined) views.
Как дополнительная оптимизация, может пропасть group by, если мы отфильтруем все записи по полям group by.

7. Group by placement
Может делать аггрегацию пораньше или попозже. Применяется совместно с Group by view merging (Group by pullup). По человечески сделают в следующих релизах.

8. Join Factorization
Применяется для Union и Union All запросов. Если в каждой части запроса есть одинаковые таблицы в джойне, то они выносятся во внешний запрос, а UNION ALL/UNION проходит без лишних объединений.

9. Predicate PullUp
Поднимает предикаты фильтрации во внешний запрос. Дорогими для выполнения считаются предикаты фильтрации, содержащие функции, пользовательсие операторы, подзапросы.
В настоящее время работает если во внешнем запросе указан rownum <= ...

10. Set operator into join
Преобразовывает операторы minus и intersect к antijoin, innerjoin, semijoin

11. Or into UNION ALL

Недостатком может стать то, что предикат OR применяется после UNION ALL и можем привести к Cartesian (к сожалению авторы ничем не пояснили эту фразу)

Общее

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

Комментариев нет: