В случае многотабличных подзапросов с EXISTS или ANY, как правило, не представляется возможным просто сливать подзапросы с содержащим их блоком запроса, так как возможен нежелательный эффект появления дубликатов строк, которых не было в результатах исходного запроса. Для многотабличных подзапросов с NOT EXISTS или ALL также не представляется возможным просто сливать подзапросы с содержащим их блоком запроса, так как соединение таблиц подзапроса следует выполнять до антисоединения с внешней таблицей. В этих случаях следует создавать встраиваемые представления, содержащие таблицы подзапросов. Для устранения вложенности коррелированных подзапросов, содержащих агрегаты, также требуется создание встраиваемых представлений с GROUP BY. Еще раз рассмотрим запрос Q1:
Q1
SELECT e1.employee_name, j.job_title FROM employees e1, job_history j WHERE e1.emp_id = j.emp_id and j.start_date > '19980101' and e1.salary > (SELECT AVG (e2.salary) FROM employees e2 WHERE e2.dept_id = e1.dept_id) and e1_dept_id IN (SELECT dept_id FROM departaments d, locations l WHERE d.loc_id = l.loc_id and l.country_id = 'US');
Рассмотрим преобразованный запрос Q10, в котором вложенность первого подзапроса устранена за счет образования встроенного представления.
Q10
SELECT e1.employee_name, j.job_title FROM employees e1, job_history j, (SELECT AVG (e2.salary) avg_sal, dept_id FROM employees e2 GROUP BY dept_id) V WHERE e1.emp_id = j.emp_id and j.start_date > '19980101' and e1.dept_id = V.dept_id and e1.salary > V.avg_sal and e1_dept_id IN (SELECT dept_id FROM departaments d, locations l WHERE d.loc_id = l.loc_id and l.country_id = 'US');
Непреобразованный запрос Q1 может лучше выполняться с использованием стратегии TIS, если внешний блок запроса значительно сокращает число кортежей таблицы employee, для которых требуется вычислить превышение средней зарплаты; кроме того, TIS может быть весьма эффективна, если на локальном столбце (т.е. на e2.dept_id) предиката корреляции имеется индекс. С другой стороны, преобразованный запрос позволяет рассматривать различные порядки и методы соединения, и для этого требуется выполнение операций агрегирования и группировки только один раз. Поэтому решение об устранении таких подзапросов должно основываться на оценке стоимости.
Преобразование, основанное на оценке стоимости, было введено в Oracle 10g. В версиях, предшествующих Oracle 10g, устранение вложенных подзапросов с образованием встраиваемых представлений основывалось на эвристиках. Немного упрощенный вариант этого эвристического правила можно сформулировать следующим образом: если во внешнем запросе имеются предикаты фильтрации и существуют индексы на локальных столбцах предиката корреляции подзапроса, то вложенность подзапроса устранять не следует.
В подразделе 4.1 мы приводим результаты производительности преобразований, основанных на оценке стоимости, в сравнении с результатами преобразований, основанных на эвристиках.