记录ob中部分执行计划的疑惑

mysql> CREATE TABLE p_tb(c1 INT PRIMARY KEY, c2 INT, c3 VARCHAR(100), KEY i_c2(c2)) PARTITION BY HASH(c1) PARTITIONS 4;
Query OK, 0 rows affected (0.16 sec)
mysql> EXPLAIN select * from p_tb where c2<10 and c3='1';
+--------------------------------------------------------------------------------------+
| Query Plan                                                                           |
+--------------------------------------------------------------------------------------+
| ===============================================================                      |
| |ID|OPERATOR                 |NAME      |EST.ROWS|EST.TIME(us)|                      |
| ---------------------------------------------------------------                      |
| |0 |PX COORDINATOR           |          |1       |23          |                      |
| |1 |└─EXCHANGE OUT DISTR     |:EX10000  |1       |22          |                      |
| |2 |  └─PX PARTITION ITERATOR|          |1       |20          |                      |
| |3 |    └─TABLE RANGE SCAN   |p_tb(i_c2)|1       |20          |                      |
| ===============================================================                      |
| Outputs & filters:                                                                   |
| -------------------------------------                                                |
|   0 - output([INTERNAL_FUNCTION(p_tb.c1, p_tb.c2, p_tb.c3)]), filter(nil), rowset=16 |
|   1 - output([INTERNAL_FUNCTION(p_tb.c1, p_tb.c2, p_tb.c3)]), filter(nil), rowset=16 |
|       dop=1                                                                          |
|   2 - output([p_tb.c1], [p_tb.c2], [p_tb.c3]), filter(nil), rowset=16                |
|       force partition granule                                                        |
|   3 - output([p_tb.c1], [p_tb.c2], [p_tb.c3]), filter([p_tb.c3 = '1']), rowset=16    |
|       access([p_tb.c1], [p_tb.c2], [p_tb.c3]), partitions(p[0-3])                    |
|       is_index_back=true, is_global_index=false, filter_before_indexback[false],     |
|       range_key([p_tb.c2], [p_tb.c1]), range(NULL,MAX ; 10,MIN),                     |
|       range_cond([p_tb.c2 < 10])                                                     |
+--------------------------------------------------------------------------------------+
20 rows in set (0.14 sec)

range_key([p_tb.c2], [p_tb.c1]), range(NULL,MAX ; 10,MIN), 

是不是有很多同学对range_key和range有疑惑呢?

其实是这样的:

定义解析

  1. range_key:
  • 含义: 表示范围扫描所依赖的键(Key),通常是索引或主键的列。
  • 作用: 定义了扫描的“维度”或“顺序”,即按照哪些列进行范围查找。
  • 格式: [col1], [col2], …,列出所有参与范围扫描的列。
  1. range:
  • 含义: 表示 range_key 中各列的具体范围条件。
  • 作用: 指定每个键列的起始值和结束值,描述数据的筛选范围。
  • 格式: (start1,start2,… ; end1,end2,…),用分号分隔起点和终点,多个列用逗号分隔。
  1. 对应关系:
  • range_key 的每一列对应 range 中的一个范围条件。
  • range 的起点和终点分别限定了 range_key 中对应列的取值范围。
  • 如果某列没有具体范围限制,可能用 NULL(无下界)或 MAX(无上界)表示。
range_key([p_tb.c2], [p_tb.c1]), range(NULL,MAX ; 10,MIN), 

p_tb.c2的扫描范围为:(NULL,10)
p_tb.c1的扫描范围为: (MAX,MIN)

仅仅记录而已,供其他不明白的小伙伴学习交流。欢迎指正

4 个赞

蹲等!!!

1 个赞