文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美國信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

10.2.1.5 引擎條件下推最佳化

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

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

假設 NDB Cluster 資料表的定義如下

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

引擎條件下推的其他支援比較包括下列項目

  • 欄位 [NOT] LIKE 模式

    模式 必須是包含要比對模式的字串文字;如需語法,請參閱 第 14.8.1 節,「字串比較函式與運算子」

  • 欄位 IS [NOT] NULL

  • 欄位 IN (值清單)

    值清單 中的每個項目都必須是常數、文字值。

  • 欄位 BETWEEN 常數1 AND 常數2

    常數1常數2 都必須是常數、文字值。

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

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

[mysqld]
optimizer_switch=engine_condition_pushdown=off

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

SET optimizer_switch='engine_condition_pushdown=off';

限制。引擎條件下推受限於以下限制:

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

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

  • 比較中使用的欄位不能是任何 BLOBTEXT 類型。此排除也適用於 JSONBITENUM 欄位。

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

  • 不直接支援聯結;涉及多個表格的條件會在可能的情況下單獨下推。使用擴展的 EXPLAIN 輸出,以判斷實際下推了哪些條件。請參閱 第 10.8.3 節,「擴展 EXPLAIN 輸出格式」

先前,引擎條件下推僅限於參考條件要下推的同一個表格的欄位值的術語。在 NDB 9.0 中,也可以從查詢計畫中較早的表格參考下推條件中的欄位值。這減少了在聯結處理期間 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)