MySQL 8.0 リファレンスマニュアル


8.2.2.5 導出条件プッシュダウン最適化

MySQL 8.0.22 以降では、適格なサブクエリーの導出条件プッシュダウンがサポートされています。 SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i > constant などのクエリーでは、多くの場合、外部 WHERE 条件を導出テーブルにプッシュダウンできます (この場合、SELECT * FROM (SELECT i, j FROM t1 WHERE i > constant) AS dt になります)。 導出テーブルを外部クエリーにマージできない場合 (導出テーブルで集計が使用されている場合など)、外部 WHERE 条件を導出テーブルにプッシュダウンすると、処理する必要がある行数が減り、クエリーの実行が高速化されます。

注記

MySQL 8.0.22 より前では、導出テーブルが実体化されているがマージされていない場合、MySQL はテーブル全体を実体化し、結果のすべての行を WHERE 条件で修飾していました。 これは、導出条件プッシュダウンが有効になっていない場合や、なんらかの理由で採用できない場合にも当てはまります。

次の状況では、外部 WHERE 条件を導出実体化テーブルにプッシュダウンできます:

  • 導出テーブルで集計関数またはウィンドウ関数が使用されていない場合は、外部 WHERE 条件を直接プッシュダウンできます。 これには、ANDOR またはその両方と結合された複数の述語を持つ WHERE 条件が含まれます。

    たとえば、クエリー SELECT * FROM (SELECT f1, f2 FROM t1) AS dt WHERE f1 < 3 AND f2 > 11SELECT f1, f2 FROM (SELECT f1, f2 FROM t1 WHERE f1 < 3 AND f2 > 11) AS dt としてリライトされます。

  • 導出テーブルに GROUP BY があり、ウィンドウ関数を使用しない場合、GROUP BY の一部ではない 1 つ以上のカラムを参照する外部 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 > 10SELECT * 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 > 10GROUP BY カラムを参照しますが、述語 sum > 100GROUP 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 が含まれている場合、最適化は使用できません。

  • 導出テーブルでは LIMIT 句を使用できません。

  • サブクエリーを含む条件はプッシュダウンできません。

  • 導出テーブルが外部結合の内部テーブルである場合、最適化は使用できません。

  • 実体化導出テーブルが共通テーブル式である場合、条件が複数回参照されても条件はプッシュされません。

  • 条件が derived_column > ? 形式の場合は、パラメータを使用して条件をプッシュダウンできます。 外部 WHERE 条件の導出カラムが、基礎となる導出テーブルに ? を持つ式である場合、この条件はプッシュダウンできません。


関連キーワード:  テーブル, 条件, 導出, WHERE, プッシュダウン, FROM, インデックス, クエリー, InnoDB, 外部