文件首頁
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


MySQL 8.4 參考手冊  /  ...  /  引擎條件下推最佳化

10.2.1.5 引擎條件下推最佳化

此最佳化可提高非索引欄位與常數之間直接比較的效率。在這種情況下,條件會下推至儲存引擎以進行評估。此最佳化只能由 NDB 儲存引擎使用。

對於 NDB 叢集,此最佳化可以消除在叢集的資料節點和發出查詢的 MySQL 伺服器之間,透過網路傳送不符合的列的需求,並且可以將使用條件下推的查詢速度提高 5 到 10 倍,與未使用條件下推的情況相比。

假設 NDB 叢集資料表的定義如下

CREATE TABLE t1 (
    a INT,
    b INT,
    KEY(a)
) ENGINE=NDB;

引擎條件下推可以用於查詢,例如這裡顯示的查詢,其中包含非索引欄位和常數之間的比較

SELECT a, b FROM t1 WHERE b = 10;

可以在 EXPLAIN 的輸出中看到引擎條件下推的使用

mysql> EXPLAIN SELECT a, b FROM t1 WHERE b = 10\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 10
        Extra: Using where with pushed condition

但是,引擎條件下推無法用於以下查詢

SELECT a,b FROM t1 WHERE a = 10;

引擎條件下推在這裡不適用,因為欄位 a 上存在索引。(索引存取方法會更有效率,因此會優先選擇條件下推。)

當索引欄位使用 >< 運算子與常數比較時,也可以使用引擎條件下推

mysql> EXPLAIN SELECT a, b FROM t1 WHERE a < 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
         type: range
possible_keys: a
          key: a
      key_len: 5
          ref: NULL
         rows: 2
        Extra: Using where with pushed condition

引擎條件下推的其他支援比較包括以下

  • column [NOT] LIKE pattern

    pattern 必須是包含要比對之模式的字串常值;有關語法,請參閱 第 14.8.1 節「字串比較函式和運算子」

  • column IS [NOT] NULL

  • column IN (value_list)

    value_list 中的每個項目都必須是常數、常值。

  • column BETWEEN constant1 AND constant2

    constant1constant2 都必須是常數、常值。

在前面清單中的所有情況下,條件都有可能轉換為欄位與常數之間的一或多個直接比較的形式。

引擎條件下推預設為啟用。若要在伺服器啟動時停用它,請將 optimizer_switch 系統變數的 engine_condition_pushdown 旗標設定為 off。例如,在 my.cnf 檔案中,使用這些行

[mysqld]
optimizer_switch=engine_condition_pushdown=off

在執行階段,像這樣停用條件下推

SET optimizer_switch='engine_condition_pushdown=off';

限制。  引擎條件下推受到以下限制

  • 引擎條件下推僅由 NDB 儲存引擎支援。

  • 在 NDB 8.4 中,只要欄位的類型完全相同,包括相同的正負號、長度、字元集、精確度和刻度(如果適用),則可以彼此比較欄位。

  • 用於比較的欄位不能是 BLOBTEXT 類型。此排除規則也適用於 JSONBITENUM 欄位。

  • 要與欄位比較的字串值必須使用與該欄位相同的校對規則。

  • 不直接支援聯結;涉及多個資料表的條件會盡可能分開推送。使用擴展的 EXPLAIN 輸出,以確定實際推送了哪些條件。請參閱第 10.8.3 節,「擴展 EXPLAIN 輸出格式」

先前,引擎條件下推僅限於參照與條件被推送到的同一資料表的欄位值。在 NDB 8.4 中,查詢計劃中較早出現的資料表的欄位值也可以從推送的條件中參照。這減少了聯結處理期間 SQL 節點必須處理的列數。篩選也可以在 LDM 執行緒中並行執行,而不是在單個 mysqld 程式中執行。這有可能顯著提高查詢效能。

如果同一聯結巢狀結構中使用的任何資料表,或其所依賴的上層聯結巢狀結構中的任何資料表上沒有不可推送的條件,則 NDB 可以使用掃描來推送外部聯結。對於半聯結也是如此,前提是採用的最佳化策略是 firstMatch(請參閱使用半聯結轉換最佳化 IN 和 EXISTS 子查詢述詞)。

在以下兩種情況下,聯結演算法不能與先前資料表的參照欄位結合使用

  1. 當任何被參照的先前資料表位於聯結緩衝區中時。在這種情況下,從掃描篩選資料表檢索的每一列都會與緩衝區中的每一列進行匹配。這表示在產生掃描篩選器時,沒有可以從中獲取欄位值的單個特定列。

  2. 當欄位來源於已推送聯結中的子運算時。這是因為當產生掃描篩選器時,尚未檢索聯結中從祖先運算參照的列。

聯結中來自祖先資料表的欄位可以被下推,前提是它們符合先前列出的要求。此處顯示了一個使用先前建立的資料表 t1 的此類查詢範例

mysql> EXPLAIN 
    ->   SELECT * FROM t1 AS x 
    ->   LEFT JOIN t1 AS y 
    ->   ON x.a=0 AND y.b>=3\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: x
   partitions: p0,p1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 4
     filtered: 100.00
        Extra: NULL
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: y
   partitions: p0,p1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 4
     filtered: 100.00
        Extra: Using where; Using pushed condition (`test`.`y`.`b` >= 3); Using join buffer (hash join)
2 rows in set, 2 warnings (0.00 sec)