文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


10.2.2.5 衍生條件下推最佳化

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 dt。當衍生資料表無法合併到外部查詢中時 (例如,如果衍生資料表使用彙總),將外部 WHERE 條件下推到衍生資料表應該會減少需要處理的列數,從而加快查詢的執行速度。

在下列情況下,外部 WHERE 條件可以下推到衍生的具體化資料表

  • 當衍生資料表不使用彙總或視窗函式時,外部 WHERE 條件可以直接下推到該資料表。這包括使用 ANDOR 或兩者聯結的多個述詞的 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 且不使用視窗函式時,可以將引用一個或多個非 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 清單包含任何對使用者變數的指派,則無法下推條件。