From bfab50ad58cf7fae63cb4effc719980abade5c31 Mon Sep 17 00:00:00 2001 From: JoyinQin <56883733+Joyinqin@users.noreply.github.com> Date: Thu, 30 Jul 2020 23:07:00 +0800 Subject: [PATCH 1/2] partitioning: update docs --- partition-pruning.md | 35 ++++++++++++++++++++++++++++++++++- partitioned-table.md | 2 +- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/partition-pruning.md b/partition-pruning.md index 30388076a6ab..540c37e59377 100644 --- a/partition-pruning.md +++ b/partition-pruning.md @@ -1,11 +1,43 @@ --- title: 分区裁剪 +summary: 了解 TiDB 分区裁剪的使用场景。 --- # 分区裁剪 分区裁剪是只有当目标表为分区表时,才可以进行的一种优化方式。分区裁剪通过分析查询语句中的过滤条件,只选择可能满足条件的分区,不扫描匹配不上的分区,进而显著地减少计算的数据量。 +例如: + +{{< copyable "sql" >}} + +```sql +CREATE TABLE t1 ( + id INT NOT NULL PRIMARY KEY, + pad VARCHAR(100) +) +PARTITION BY RANGE COLUMNS(id) ( + PARTITION p0 VALUES LESS THAN (100), + PARTITION p1 VALUES LESS THAN (200), + PARTITION p2 VALUES LESS THAN (MAXVALUE) +); +INSERT INTO t1 VALUES (1, 'test1'),(101, 'test2'), (201, 'test3'); +EXPLAIN SELECT * FROM t1 WHERE id BETWEEN 80 AND 120; +``` + +```sql ++----------------------------+---------+-----------+------------------------+------------------------------------------------+ +| id | estRows | task | access object | operator info | ++----------------------------+---------+-----------+------------------------+------------------------------------------------+ +| PartitionUnion_8 | 80.00 | root | | | +| ├─TableReader_10 | 40.00 | root | | data:TableRangeScan_9 | +| │ └─TableRangeScan_9 | 40.00 | cop[tikv] | table:t1, partition:p0 | range:[80,120], keep order:false, stats:pseudo | +| └─TableReader_12 | 40.00 | root | | data:TableRangeScan_11 | +| └─TableRangeScan_11 | 40.00 | cop[tikv] | table:t1, partition:p1 | range:[80,120], keep order:false, stats:pseudo | ++----------------------------+---------+-----------+------------------------+------------------------------------------------+ +5 rows in set (0.00 sec) +``` + ## 分区裁剪的使用场景 分区表有 Range 分区和 hash 分区两种形式,分区裁剪对两种分区表也有不同的使用场景。 @@ -195,7 +227,8 @@ explain select * from t where x between 7 and 14; 分区表达式为 `fn(col)` 的简单形式,查询条件是 `> < = >= <=` ,且 `fn` 是单调函数,可以使用分区裁剪。 -理论上所有满足单调条件(严格或者非严格)的函数都是可以支持分区裁剪。实际上,目前 TiDB 已经支持的单调函数只有: +这里单调函数是指某个函数 `fn` 满足条件:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) > fn(y)`。 +这种是严格递增的单调函数,非严格递增的单调函数也可以符合分区裁剪要求,只要函数 `fn` 满足:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) >= fn(y)`。理论上所有满足单调条件(严格或者非严格)的函数都是可以支持分区裁剪。实际上,目前 TiDB 已经支持的单调函数只有:实际上,目前 TiDB 已经支持的单调函数只有: ```sql unix_timestamp diff --git a/partitioned-table.md b/partitioned-table.md index 9d3c3d95af9f..87239b200bd1 100644 --- a/partitioned-table.md +++ b/partitioned-table.md @@ -477,7 +477,7 @@ ERROR 8200 (HY000): Unsupported optimize partition ## 分区裁剪 -有一个优化叫做“分区裁剪”,它基于一个非常简单的概念:不需要扫描那些匹配不上的分区。 +有一个优化叫做[“分区裁剪”](/partition-pruning.md),它基于一个非常简单的概念:不需要扫描那些匹配不上的分区。 假设创建一个分区表 `t1`: From b94a489871d88371bec246a2c6bce6252406b763 Mon Sep 17 00:00:00 2001 From: JoyinQ <56883733+Joyinqin@users.noreply.github.com> Date: Fri, 31 Jul 2020 18:52:29 +0800 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Lilian Lee --- partition-pruning.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/partition-pruning.md b/partition-pruning.md index 540c37e59377..c44a9199c54e 100644 --- a/partition-pruning.md +++ b/partition-pruning.md @@ -225,10 +225,9 @@ explain select * from t where x between 7 and 14; ##### 场景三 -分区表达式为 `fn(col)` 的简单形式,查询条件是 `> < = >= <=` ,且 `fn` 是单调函数,可以使用分区裁剪。 +分区表达式为 `fn(col)` 的简单形式,查询条件是 `>` `<` `=` `>=` `<=` 之一,且 `fn` 是单调函数,可以使用分区裁剪。 -这里单调函数是指某个函数 `fn` 满足条件:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) > fn(y)`。 -这种是严格递增的单调函数,非严格递增的单调函数也可以符合分区裁剪要求,只要函数 `fn` 满足:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) >= fn(y)`。理论上所有满足单调条件(严格或者非严格)的函数都是可以支持分区裁剪。实际上,目前 TiDB 已经支持的单调函数只有:实际上,目前 TiDB 已经支持的单调函数只有: +关于 `fn` 函数,对于任意 `x` `y`,如果 `x > y`,则 `fn(x) > fn(y)`,那么这种是严格递增的单调函数。非严格递增的单调函数也可以符合分区裁剪要求,只要函数 `fn` 满足:对于任意 `x` `y`,如果 `x > y`,则 `fn(x) >= fn(y)`。理论上,所有满足单调条件(严格或者非严格)的函数都支持分区裁剪。目前,TiDB 支持的单调函数如下: ```sql unix_timestamp @@ -292,4 +291,4 @@ explain select * from t2 where x < (select * from t1 where t2.x < t1.x and t2.x 14 rows in set (0.00 sec) ``` -这个查询每从 `t2` 读取一行,都会去分区表 `t1` 上进行查询,理论上这时会满足 `t1.x > val` 的过滤条件,但实际上由于分区裁剪只作用于查询计划生成阶段,而不是执行阶段,因而不会做裁剪。 \ No newline at end of file +这个查询每从 `t2` 读取一行,都会去分区表 `t1` 上进行查询,理论上这时会满足 `t1.x > val` 的过滤条件,但实际上由于分区裁剪只作用于查询计划生成阶段,而不是执行阶段,因而不会做裁剪。