Расширенная оптимизация подзапросов в Oracle


Сращивание подзапросов разных типов


Для сращивание двух конъюнктивных подзапросов, удовлетворяющих свойству включения и имеющих разные типы, требуется применение другого метода. Рассмотрим запрос Q4, который является несколько упрощенным вариантом запроса 21 из TPC-H.

Q4

SELECT s_name FROM supplier, lineitem L1 WHERE s_suppkey = l_suppkey AND EXISTS (SELECT * FROM lineitem L2 WHERE l_orderkey = L1.l_orderkey AND l_suppkey <> L1.l_suppkey) AND NOT EXISTS (SELECT * FROM lineitem L3 WHERE l_orderkey = L1.l_orderkey AND l_suppkey <> L1.l_suppkey AND l_receiptdate > l_commitdate);

Два подзапроса в Q4 отличаются только своими типами и тем, что в подзапросе с NOT EXISTS имеется дополнительный предикат фильтрации l_receipt_date > l_commitdate. Сращивание подзапросов приводит к запросу Q5 с единственным подзапросом с EXISTS, в результате чего устраняется один экземпляр таблицы lineitem.

Q5

SELECT s_name FROM supplier, lineitem L1 WHERE s_suppkey = l_suppkey AND EXISTS (SELECT 1 FROM lineitem L2 WHERE l_orderkey = L1.l_orderkey AND l_suppkey <> L1.l_suppkey) HAVING SUM(CASE WHEN l_receiptdate > l_commitdate THEN 1 ELSE 0 END) = 0);

Агрегатная функция раздела HAVING возвращает общее количество строк, удовлетворяющих предикату подзапроса. Раздел HAVING, включенный в срощенный подзапрос, является новым предикатом фильтрации, который проверяет, удовлетворяет ли какая-либо строка предикату подзапроса, тем самым имитируя поведение удаленного подзапроса с NOT EXISTS.

Для каждого набора корреляционных значений подзапросы в Q4 могут находиться в одном из трех состояний:

  • Если подзапрос EXISTS не возвращает строк (т.е. вычисляется в FALSE), то результатом конъюнкции двух подзапросов является FALSE. В Q5 раздел HAVING применяется к пустому множеству, и срощенный подзапрос с EXISTS также вычисляется в FALSE.

  • Если подзапрос с EXISTS

    возвращает несколько строк (т.е. вычисляется в TRUE), и подзапрос NOT EXISTS тоже возвращает несколько строк (т.е. вычисляется в FALSE), то результатом конъюнкции двух подзапросов является FALSE. В Q5 раздел HAVING применяется к непустому множеству строк, для которых l_receiptdate > l_commitdate, и потому вычисляется в FALSE; таким образом, срощенный подзапрос вычисляется в FALSE.




  • - Начало -  - Назад -  - Вперед -