下推到 TiKV 的表达式列表

当 TiDB 从 TiKV 中读取数据的时候,TiDB 会尽量下推一些表达式运算到 TiKV 中,从而减少数据传输量以及 TiDB 单一节点的计算压力。本文将介绍 TiDB 已支持下推的表达式,以及如何禁止下推特定表达式。

已支持下推的表达式列表

表达式分类具体操作
逻辑运算AND (&&), OR (||), NOT (!)
比较运算<, <=, =, != (<>), >, >=, <=>, IN(), IS NULL, LIKE, IS TRUE, IS FALSE, COALESCE()
数值运算+, -, *, /, ABS(), CEIL(), CEILING(), FLOOR()
控制流运算CASE, IF(), IFNULL()
JSON 运算JSON_TYPE(json_val),
JSON_EXTRACT(json_doc, path[, path] ...),
JSON_OBJECT(key, val[, key, val] ...),
JSON_ARRAY([val[, val] ...]),
JSON_MERGE(json_doc, json_doc[, json_doc] ...),
JSON_SET(json_doc, path, val[, path, val] ...),
JSON_INSERT(json_doc, path, val[, path, val] ...),
JSON_REPLACE(json_doc, path, val[, path, val] ...),
JSON_REMOVE(json_doc, path[, path] ...)
日期运算DATE_FORMAT()

禁止特定表达式下推

已支持下推的表达式列表中的函数和运算符,或特定的数据类型(仅限 ENUM 类型BIT 类型)的计算过程因下推而出现异常时,你可以使用黑名单功能禁止其下推,从而快速恢复 TiDB 业务。具体而言,你可以将函数名、运算符名,或数据列类型加入黑名单 mysql.expr_pushdown_blacklist 中,以禁止特定表达式下推。具体方法,请参阅加入黑名单

mysql.expr_pushdown_blacklist 的 schema 如下:

tidb> desc mysql.expr_pushdown_blacklist; +------------+--------------+------+------+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+------+-------------------+-------+ | name | char(100) | NO | | NULL | | | store_type | char(100) | NO | | tikv,tiflash,tidb | | | reason | varchar(200) | YES | | NULL | | +------------+--------------+------+------+-------------------+-------+ 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:用于记录该函数被加入黑名单的原因。

加入黑名单

执行以下步骤,可将一个或多函数名、运算符名或数据类型(仅限 ENUM 类型BIT 类型)加入黑名单:

  1. mysql.expr_pushdown_blacklist 插入以下内容:

    • 希望禁止下推的函数名、运算符名或数据类型
    • 希望禁止下推的存储引擎
  2. 执行 admin reload expr_pushdown_blacklist;

移出黑名单

执行以下步骤,可将一个或多个函数名、运算符名或数据类型移出黑名单:

  1. mysql.expr_pushdown_blacklist 表中删除对应的函数名、运算符名或数据类型。
  2. 执行 admin reload expr_pushdown_blacklist;

黑名单使用示例

以下示例首先将函数 DATE_FORMAT()、运算符 > 及 数据类型 BIT 加入黑名单,然后再将运算符 > 从黑名单中移出。

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

tidb> create table t(a int); Query OK, 0 rows affected (0.06 sec) tidb> explain select * from t where a < 2 and a > 2; +-------------------------+----------+-----------+---------------+------------------------------------+ | id | estRows | task | access object | operator info | +-------------------------+----------+-----------+---------------+------------------------------------+ | TableReader_7 | 0.00 | root | | data:Selection_6 | | └─Selection_6 | 0.00 | cop[tikv] | | gt(ssb_1.t.a, 2), lt(ssb_1.t.a, 2) | | └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | +-------------------------+----------+-----------+---------------+------------------------------------+ 3 rows in set (0.00 sec) tidb> insert into mysql.expr_pushdown_blacklist values('date_format()', 'tikv',''), ('>','tikv',''), ('bit','tikv',''); Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 tidb> admin reload expr_pushdown_blacklist; Query OK, 0 rows affected (0.00 sec) tidb> explain select * from t where a < 2 and a > 2; +-------------------------+----------+-----------+---------------+------------------------------------+ | id | estRows | task | access object | operator info | +-------------------------+----------+-----------+---------------+------------------------------------+ | Selection_7 | 10000.00 | root | | gt(ssb_1.t.a, 2), lt(ssb_1.t.a, 2) | | └─TableReader_6 | 10000.00 | root | | data:TableFullScan_5 | | └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | +-------------------------+----------+-----------+---------------+------------------------------------+ 3 rows in set (0.00 sec) tidb> delete from mysql.expr_pushdown_blacklist where name = '>'; Query OK, 1 row affected (0.01 sec) tidb> admin reload expr_pushdown_blacklist; Query OK, 0 rows affected (0.00 sec) tidb> explain select * from t where a < 2 and a > 2; +---------------------------+----------+-----------+---------------+--------------------------------+ | id | estRows | task | access object | operator info | +---------------------------+----------+-----------+---------------+--------------------------------+ | Selection_8 | 0.00 | root | | lt(ssb_1.t.a, 2) | | └─TableReader_7 | 0.00 | root | | data:Selection_6 | | └─Selection_6 | 0.00 | cop[tikv] | | gt(ssb_1.t.a, 2) | | └─TableFullScan_5 | 10000.00 | cop[tikv] | table:t | keep order:false, stats:pseudo | +---------------------------+----------+-----------+---------------+--------------------------------+ 4 rows in set (0.00 sec)
运算符原始名称运算符别名
<lt
>gt
<=le
>=ge
=eq
!=ne
<>ne
<=>nulleq
|bitor
&&bitand
||or
!not
inin
+plus
-minus
*mul
/div
DIVintdiv
IS NULLisnull
IS TRUEistrue
IS FALSEisfalse