不确定题目:表T1是一个RANGE分区表 ,其DDL如下所示:......; 则以下SQL语句查询T1时需要访问的分区情况是:SELECT * FROM T1 WHERE C1>=199;

表T1是一个RANGE分区表 ,其DDL如下所示:CREATE TABLE t1(C1 INT, C2 INT) PARTITION BY RANGE(C1+1) (PARTITION P0 VALUES LESS THAN(100) PARTITION P1 VALUES LESS THAN(200) PARTITION P2 VALUES LESS THAN(MAXVALUE)); 则以下SQL语句查询T1时需要访问的分区情况是:SELECT * FROM T1 WHERE C1>=199;

A. 需访问分区P1和P2

B. 仅访问分区P1

C. 仅访问分区P2

D. 需访问全部分区

1 个赞

正确答案是 A. 需访问分区 P1 和 P2
首先明确分区规则:表 t1 是按 C1+1 进行范围分区的:
P0:C1+1 < 100 → C1 < 99
P1:100 ≤ C1+1 < 200 → 99 ≤ C1 < 199
P2:C1+1 ≥ 200 → C1 ≥ 199
查询条件是 WHERE C1 >= 199,我们代入分区规则:
当 C1=199 时,C1+1=200,刚好满足 C1+1 < 200(P1 的上限是小于 200)吗?不,P1 的范围是 C1+1 < 200,而 C1=199 时 C1+1=200,不满足 C1+1 < 200,所以 C1=199 不属于 P1,而是属于 P2 吗?这里有个关键点:分区条件是按 C1+1 计算的,而查询条件是直接用 C1 写的,分区裁剪时,数据库需要计算分区键的值。
更严谨的推导:
分区 P1 的范围:C1+1 < 200 → C1 < 199,不包含 C1=199
分区 P2 的范围:C1+1 ≥ 200 → C1 ≥ 199,包含 C1=199 及以上的值
那为什么会需要访问 P1 和 P2?这里的关键是:分区键是表达式 C1+1,而查询条件 C1 >= 199 无法被优化器直接转换为 C1+1 的范围,导致无法完全裁剪 P1 分区。
因为查询条件是基于原始列 C1,而分区键是表达式 C1+1,数据库无法确定 C1 >= 199 时 C1+1 的值是否完全不落在 P1 分区的范围内(虽然数学上是完全不落在的,但优化器对分区键为表达式的裁剪能力有限),所以会保守地扫描所有可能的分区,即 P1 和 P2。

正确答案是 A

aaa