MySQL 支持对符合条件的子查询进行派生条件下推。对于类似 SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i >
的查询,在许多情况下可以将外部 constant
WHERE
条件下推到派生表,在本例中将产生 SELECT * FROM (SELECT i, j FROM t1 WHERE i >
。当派生表无法合并到外部查询时(例如,如果派生表使用聚合),将外部 constant
) AS dtWHERE
条件下推到派生表应减少需要处理的行数,从而加快查询执行速度。
外部 WHERE
条件可以在以下情况下下推到派生物化表
当派生表不使用聚合或窗口函数时,外部
WHERE
条件可以直接下推到它。这包括WHERE
条件使用AND
、OR
或两者连接的多个谓词。例如,查询
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
并且不使用窗口函数时,引用一个或多个不在GROUP BY
中的列的外部WHERE
条件可以作为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
部分的列的谓词,以及引用不在其中的列的谓词,前者的谓词作为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
中,外部WHERE
子句中的谓词i > 10
引用了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
列表包含对用户变量的任何赋值,则条件不能下推。