优化规则与表达式下推的黑名单

    优化规则黑名单是针对优化规则的调优手段之一,主要用于手动禁用一些优化规则。

    禁用优化规则

    当某些优化规则在一些特殊查询中的优化结果不理想时,可以使用优化规则黑名单禁用一些优化规则。

    使用方法

    • 如果你想禁用某些规则,可以在 mysql.opt_rule_blacklist 表中写入规则的名字,例如:

      执行以下 SQL 语句可让禁用规则立即生效,包括相应 TiDB Server 的所有旧链接:

      1. admin reload opt_rule_blacklist;
      1. delete from mysql.opt_rule_blacklist where name in ("join_reoder", "topn_push_down");
      2. admin reload opt_rule_blacklist;

    表达式下推黑名单

    表达式下推黑名单是针对表达式下推的调优手段之一,主要用于对于某些存储类型手动禁用一些表达式。

    表达式分类 具体操作
    AND (&&), OR (||), NOT (!)
    比较运算 <, <=, =, != (<>), >, >=, , IN(), IS NULL, LIKE, IS TRUE, IS FALSE,
    数值运算 +, -, *, /, , CEIL(), , FLOOR()
    CASE, , IFNULL()
    [JSON_TYPE(json_val)][json_type],
    [JSON_EXTRACT(json_doc, path[, path] …)][json_extract],
    [JSON_UNQUOTE(json_val)][json_unquote],
    [JSON_OBJECT(key, val[, key, val] …)][json_object],
    [JSON_ARRAY([val[, val] …])][json_array],
    [JSON_MERGE(json_doc, json_doc[, json_doc] …)][json_merge],
    [JSON_SET(json_doc, path, val[, path, val] …)][json_set],
    [JSON_INSERT(json_doc, path, val[, path, val] …)][json_insert],
    [JSON_REPLACE(json_doc, path, val[, path, val] …)][json_replace],
    [JSON_REMOVE(json_doc, path[, path] …)][json_remove]
    日期运算

    禁止特定表达式下推

    当函数的计算过程由于下推而出现异常时,可通过黑名单功能禁止其下推来快速恢复业务。具体而言,你可以将上述支持的函数或运算符名加入黑名单 mysql.expr_pushdown_blacklist 中,以禁止特定表达式下推。

    mysql.expr_pushdown_blacklist 的 schema 如下:

      1. +------------+--------------+------+------+-------------------+-------+
      2. | Field | Type | Null | Key | Default | Extra |
      3. +------------+--------------+------+------+-------------------+-------+
      4. | store_type | char(100) | NO | | tikv,tiflash,tidb | |
      5. | reason | varchar(200) | YES | | NULL | |
      6. +------------+--------------+------+------+-------------------+-------+
      7. 3 rows in set (0.00 sec)

      以上结果字段解释如下:

      • name:禁止下推的函数名。
      • store_type:用于指明希望禁止该函数下推到哪些组件进行计算。组件可选 tidbtikvtiflashstore_type 不区分大小写,如果需要禁止向多个存储引擎下推,各个存储之间需用逗号隔开。
        • store_typetidb 时表示在读取 TiDB 内存表时,是否允许该函数在其他 TiDB Server 上执行。
        • store_typetikv 时表示是否允许该函数在 TiKV Server 的 Coprocessor 模块中执行。
        • store_typetiflash 时表示是否允许该函数在 TiFlash Server 的 Coprocessor 模块中执行。
      • reason:用于记录该函数被加入黑名单的原因。

      加入黑名单

      如果要将一个或多个函数或运算符加入黑名单,执行以下步骤:

      1. mysql.expr_pushdown_blacklist 插入对应的函数名或运算符名以及希望禁止下推的存储引擎集合。

      2. 执行 admin reload expr_pushdown_blacklist;

      移出黑名单

      如果要将一个或多个函数及运算符移出黑名单,执行以下步骤:

      1. 执行 admin reload expr_pushdown_blacklist;

      表达式黑名单用法示例

      以下示例首先将运算符 <> 加入黑名单,然后将运算符 > 从黑名单中移出。

      黑名单是否生效可以从 结果中进行观察(参见如何理解 explain 结果)。

      1. 对于以下 SQL 语句,where 条件中的 a < 2a > 2 可以下推到 TiKV 进行计算。

        1. explain select * from t where a < 2 and a > 2;
      2. mysql.expr_pushdown_blacklist 表中插入禁用表达式,并且执行 admin reload expr_pushdown_blacklist

        1. insert into mysql.expr_pushdown_blacklist values('<','tikv',''), ('>','tikv','');
        1. Query OK, 2 rows affected (0.01 sec)
        2. Records: 2 Duplicates: 0 Warnings: 0
        1. admin reload expr_pushdown_blacklist;
        1. Query OK, 0 rows affected (0.00 sec)
      3. 重新观察执行计划,发现表达式下推黑名单生效,where 条件中的 <> 没有被下推到 TiKV Coprocessor 上。

        1. explain select * from t where a < 2 and a > 2;
        1. delete from mysql.expr_pushdown_blacklist where name = '>';
        1. Query OK, 1 row affected (0.01 sec)
        1. admin reload expr_pushdown_blacklist;
        1. Query OK, 0 rows affected (0.00 sec)