Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


10.2.2.5 Derived Condition Pushdown 优化

MySQL 支持derived condition pushdown 对于合格的子查询。对于一个查询,如SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i > constant,在许多情况下,可以将外部WHERE条件推送到derived table中,例如结果为SELECT * FROM (SELECT i, j FROM t1 WHERE i > constant) AS dt。当derived table不能被合并到外部查询(例如,如果derived table使用聚合函数)时,推送外部WHERE条件到derived table中将减少需要处理的行数,从而加速查询执行。

外部WHERE条件可以在以下情况下被推送到derived materialized tables:

  • 当derived table不使用聚合或窗口函数时,外部WHERE条件可以直接被推送到它中。这包括WHERE条件具有多个谓词,使用ANDOR或两者。

    例如,查询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中,外层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标志(在本次发布中添加)设置为onoptimizer_switch禁用,可以使用DERIVED_CONDITION_PUSHDOWN优化提示来启用它。要为特定查询禁用该优化,使用NO_DERIVED_CONDITION_PUSHDOWN优化提示。

以下是派生表条件下推优化的限制和限制:

  • 派生表条件下推优化可以与UNION查询一起使用,但以下例外情况除外:

    • 如果UNION查询中的任何物化派生表是递归公共表达式(见递归公共表达式),则不能使用条件下推优化。

    • 包含非确定性表达式的条件无法被下推到派生表中。

  • 派生表不能使用LIMIT子句。

  • 包含子查询的条件无法被下推。

  • 如果派生表是外连接的内表,则优化不能被使用。

  • 如果物化派生表是公共表达式,且被多次引用,则不会将条件下推到它中。

  • 可以将参数条件下推,如果条件为derived_column > ?。如果派生列在外部WHERE条件中是一个表达式,其中包含?,则不能下推该条件。

  • 对于使用ALGORITHM=TEMPTABLE创建的视图查询,如果条件是对视图本身,而不是对视图中的表,则多个等式不会被识别,在优化时无法下推。因为,优化查询时,条件下推发生在解析阶段,而多个等式传播发生在优化阶段。

    在使用ALGORITHM=MERGE的视图中,这不是问题,因为可以传播等式并推下条件。

  • 如果派生表的SELECT列表包含对用户变量的赋值,不能推下条件。