• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 储存引擎下的优化

    种优化提高了非索引列和常量之间直接比较的效率。在这种情况下,条件被“下推”到存储引擎进行评估。此优化只能由NDB存储引擎使用。

    对于NDB群集,此优化可以消除在群集的数据节点和发出查询的MySQL服务器之间通过网络发送不匹配的行的需求,并且可以将查询的使用速度提高5到10倍(在某些情况下)可以但不使用条件下推的地方。

    假设NDB群集表定义如下:

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

    条件下推可用于查询,例如此处显示的查询,其中包括未索引列和常量之间的比较:

    SELECT  , b FROM t1 WHERE b = 10;
    

    条件下推的使用可以在以下输出中看到EXPLAIN

    mysql> EXPLAIN SELECT  ,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
    Extr  : Using where with pushed condition
    

    但是,条件下推不能与以下查询一起使用:

    SELECT  ,b FROM t1 WHERE a = 10;
    

    条件下推不适用于此处,因为column上存在索引。(索引访问方法将更有效,因此优先选择条件下推。)

    使用><运算符将索引列与常量进行比较时,也可以使用条件下推:

    mysql> EXPLAIN SELECT  , 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
    Extr  : Using where with pushed condition
    

    条件下推的其他受支持的比较包括:

    • column[NOT] LIKE pattern

      pattern必须是包含要匹配的模式的字符串文字;有关语法,请参见“字符串比较函数和运算符”。

    • column IS[NOT] NULL
    • column IN(value_list)

      中的每个项目都value_list必须是恒定的文字值。

    • column BETWEEN constant1 AND constant2

      constant1并且constant2每个值都必须是恒定的文字值。

    在上述列表中的所有情况下,都有可能将条件转换为列与常量之间的一个或多个直接比较的形式。

    默认情况下,引擎状态下推处于启用状态。要在服务器启动时禁用它,请设置optimizer_switch系统变量。例如,在my.cnf文件中,使用以下几行:

    [mysqld]
    optimizer_switch=engine_condition_pushdown=off
    

    在运行时,禁用条件下推,如下所示:

    SET optimizer_switch='engine_condition_pushdown=off';
    

    局限性。引擎状态下推受以下限制:

    • 条件下推仅受NDB存储引擎支持。
    • 在NDB 8.0.18之前,可以将列与仅求常数值的常数或表达式进行比较。在NDB 8.0.18及更高版本中,只要适用于相同类型的列(包括相同的符号,长度,字符集,精度和小数位数),它们就可以相互比较。
    • 比较中使用的列不能为BLOBTEXT类型。此排除范围也扩展到JSONBITENUM列。
    • 要与列进行比较的字符串值必须使用与列相同的排序规则。
    • 不直接支持联接;涉及多个表的条件将在可能的情况下分别推送。使用扩展EXPLAIN输出来确定实际按下了哪些条件。请参见“扩展的EXPLAIN输出格式”。

    以前,条件下推仅限于引用条件被推到的同一表中列值的术语。从NDB 8.0.16开始,查询计划中较早的表中的列值也可以从推送条件中引用。这减少了连接处理期间SQL节点必须处理的行数。过滤也可以在LDM线程中并行执行,而不是在单个mysqld进程中执行。这有可能极大地提高查询性能。

    从NDB 8.0.20开始,如果在同一联接嵌套中使用的任何表或它所依赖的联接nmest中的任何表上没有不可推动的条件,则可以推送使用扫描的外部联接。如果使用了优化策略,则对于半连接也是如此firstMatch(请参见“使用半联接转换优化 IN 和 EXISTS 子查询”)。

    在以下两种情况下,联接算法不能与先前表中的引用列结合使用:

    1. 当任何引用的先前表在连接缓冲区中时。在这种情况下,将从扫描筛选表中检索的每一行与缓冲区中的每一行进行匹配。这意味着在生成扫描过滤器时,没有单个特定的行可以从中获取列值。
    2. 当该列源自推送连接中的子操作时。这是因为生成扫描过滤器时,尚未检索到联接中祖先操作引用的行。