10.2.2.5 Оптимизация вынесения условия производной таблицы
MySQL поддерживает вынесение условия производной таблицы для подходящих подзапросов. Для запроса, такого как SELECT * FROM (SELECT
i, j FROM t1) AS dt WHERE i >
, во многих случаях возможно вынести внешнее условие constantWHERE в производную таблицу, что в данном случае приводит к SELECT * FROM (SELECT i, j FROM t1 WHERE i >
. Когда производную таблицу нельзя объединить с внешним запросом (например, если производная таблица использует агрегацию), вынесение внешнего условия constant) AS dtWHERE в производную таблицу должно уменьшить количество обрабатываемых строк и, следовательно, ускорить выполнение запроса.
Внешние условия WHERE могут быть вынесены в материализованные таблицы производных при следующих обстоятельствах:
-
Если производная таблица не использует агрегатные или оконные функции, то внешнее условие
WHEREможет быть вынесено в нее непосредственно. Это включает условияWHERE, имеющие несколько предикатов, соединенных операторами `И`, `ИЛИ` или обоими.Например, запрос
SELECT * FROM (SELECT f1, f2 FROM t1) AS dt WHERE f1 < 3 AND f2 > 11переписывается какSELECT f1, f2 FROM (SELECT f1, f2 FROM t1 WHERE f1 < 3 AND f2 > 11) AS dt. -
Если производная таблица имеет
GROUP BYи не использует оконные функции, то внешнее условиеWHERE, ссылающееся на один или несколько столбцов, которые не являются частьюGROUP BY, может быть вынесено в производную таблицу как условиеHAVING.Например,
SELECT * FROM (SELECT i, j, SUM(k) AS sum FROM t1 GROUP BY i, j) AS dt WHERE sum > 100после оптимизации вынесения условия производной таблицы переписывается какSELECT * FROM (SELECT i, j, SUM(k) AS sum FROM t1 GROUP BY i, j HAVING sum > 100) AS dt. -
Если производная таблица использует
GROUP BY, а столбцы во внешнем условииWHEREявляютсяGROUP BYстолбцами, то условияWHERE, ссылающиеся на эти столбцы, могут быть вынесены непосредственно в производную таблицу.Например, запрос
SELECT * FROM (SELECT i,j, SUM(k) AS sum FROM t1 GROUP BY i,j) AS dt WHERE i > 10переписывается какSELECT * FROM (SELECT i,j, SUM(k) AS sum FROM t1 WHERE i > 10 GROUP BY i,j) AS dt.В случае, когда внешнее условие
WHEREсодержит предикаты, ссылающиеся на столбцы, которые являются частьюGROUP BY, а также предикаты, ссылающиеся на столбцы, которые не являются частьюGROUP BY, предикаты первого типа выносятся как условияWHERE, а предикаты второго типа – как условияHAVING. Например, в запросеSELECT * FROM (SELECT i, j, SUM(k) AS sum FROM t1 GROUP BY i,j) AS dt WHERE i > 10 AND sum > 100предикатi > 10в внешнем условииWHEREссылается на столбецGROUP BY, а предикатsum > 100не ссылается ни на один столбецGROUP BY. Таким образом, оптимизация вынесения условия производной таблицы приводит к переписыванию запроса, примерно так, как показано здесь:SELECT * FROM ( SELECT i, j, SUM(k) AS sum FROM t1 WHERE i > 10 GROUP BY i, j HAVING sum > 100 ) AS dt;
Для включения вынесения условия производной таблицы переменная системы optimizer_switch должна быть установлена в значение, включающее флаг derived_condition_pushdown (добавлено в этом релизе) в значение on, что является значением по умолчанию. Если эта оптимизация отключена значением optimizer_switch, ее можно включить для конкретного запроса, используя подсказку оптимизатора DERIVED_CONDITION_PUSHDOWN. Для отключения оптимизации для данного запроса используйте подсказку оптимизатора NO_DERIVED_CONDITION_PUSHDOWN.
Следующие ограничения применяются к оптимизации вынесения условия производной таблицы:
-
Оптимизация вынесения условия производной таблицы может быть применена к
UNIONзапросам, с исключениями:Вынесение условия не может быть использовано с запросом
UNION, если любая материализованная производная таблица, которая является частьюUNION, является рекурсивным общим табличным выражением (см. Рекурсивные общие табличные выражения).Условие, содержащее недетерминированные выражения, не может быть вынесено в производную таблицу.
Производная таблица не может использовать предложение
LIMIT.Условия, содержащие подзапросы, не могут быть вынесены.
Оптимизация не может быть использована, если производная таблица является внутренней таблицей внешнего соединения.
Если материализованная производная таблица является общим табличным выражением, условия не выносятся в нее, если она ссылается несколько раз.
Условия, использующие параметры, могут быть вынесены, если условие имеет вид
. Если производный столбец во внешнем условииderived_column> ?WHEREявляется выражением, содержащим?в базовой производной таблице, это условие не может быть вынесено.-
Для запроса, в котором условие относится к таблицам представления, созданного с помощью
ALGORITHM=TEMPTABLE, а не к самому представлению, множественное равенство не распознается на этапе разрешения, и, следовательно, условие не может быть вынесено. Это происходит потому, что при оптимизации запроса вынесение условия происходит на этапе разрешения, в то время как распространение множественного равенства происходит во время оптимизации.Это не проблема в таких случаях для представления, использующего
ALGORITHM=MERGE, где равенство может быть распространено, а условие вынесено. Условие не может быть вынесено, если список
SELECTпроизводной таблицы содержит какие-либо присваивания переменным пользователя.
© 2025 Oracle
Licensed under the GPLv2 License.