文档首页
MySQL 8.4 参考手册
相关文档 下载此手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (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)