首批通过分布式安全可靠测评,为关键业务系统打造
range_index_dive_limit
更新时间:2026-07-13 22:32:57
说明
在 V4.2.x 版本中,该变量从 V4.2.5、V4.2.1 BP9 版本引入。
功能描述
range_index_dive_limit 用于指示优化器使用存储层估行时的 range 数量限制。
权限要求
- 查询变量
- Global 级别 sys 租户和所有用户租户均可以使用
SHOW VARIABLES语句或视图SYS.TENANT_VIRTUAL_GLOBAL_VARIABLE(Oracle 模式)及视图information_schema.GLOBAL_VARIABLES(MySQL 模式)查看 Global 系统变量的值。 - Session 级别 sys 租户和所有用户租户均可以使用
SHOW VARIABLES语句或视图SYS.TENANT_VIRTUAL_SESSION_VARIABLE(Oracle 模式)及视图information_schema.SESSION_VARIABLES(MySQL 模式)查看 Session 系统变量的值。
- Global 级别 sys 租户和所有用户租户均可以使用
- 修改变量
- Global 生效
- sys 租户可以直接修改 Global 系统变量的值。
- MySQL 用户租户需要拥有
SUPER或ALTER SYSTEM权限才能修改 Global 系统变量的值。 - 对于 V4.x 版本,从 V4.2.0 版本开始,Oracle 用户租户需要拥有
ALTER SYSTEM权限才能修改 Global 系统变量的值。
- Session 生效 sys 租户和所有用户租户均可以直接修改本租户的 Session 系统变量的值。
- Global 生效
属性说明
| 属性 | 描述 |
|---|---|
| 参数类型 | int |
| 默认值 | 10 |
| 取值范围 | [0, INT64_MAX]
说明其中:
|
| 生效范围 | Global/Session |
| 是否可修改 | 是 |
使用说明
修改该变量以控制优化器存储层估行时的 range 数量限制:
- 当 range 个数小于该变量时,总是选择所有 range 做存储层估行。
- 当 range 个数大于等于该变量时,随机选择
range_index_dive_limit个 range 进行存储层估行,并将估行结果等比例放大。 - 当该变量为 0 时,总是选择所有 range 做存储层估行。
- 当
range_index_dive_limit与partition_index_dive_limit同为负数时,存储层估行策略回滚到旧版本,仅对单分区 10 个 range 以内做存储层估行。
配置示例
创建表并插入数据。
obclient> CREATE TABLE t1(c1 int, c2 int, index i1(c1)); Query OK, 0 rows affected (0.173 sec) obclient> INSERT INTO t1 SELECT 1,1 FROM table(generator(10)); Query OK, 10 rows affected (0.003 sec) Records: 10 Duplicates: 0 Warnings: 0 obclient> INSERT INTO t1 SELECT 2,2 FROM table(generator(20)); Query OK, 20 rows affected (0.001 sec) Records: 20 Duplicates: 0 Warnings: 0 obclient> INSERT INTO t1 SELECT 3,3 FROM table(generator(30)); Query OK, 30 rows affected (0.001 sec) Records: 30 Duplicates: 0 Warnings: 0查看执行计划,默认场景,不超过 10 个 range 均采用存储层估行。
obclient> EXPLAIN SELECT c1 FROM t1 WHERE c1 in (1,2,3); +---------------------------------------------------------------------------------------------------------+ | Query Plan | +---------------------------------------------------------------------------------------------------------+ | ================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | -------------------------------------------------- | | |0 |TABLE RANGE SCAN|t1(i1)|60 |11 | | | ================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output([t1.c1]), filter(nil), rowset=256 | | access([t1.c1]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX), (2,MIN ; 2,MAX), (3,MIN ; 3,MAX), | | range_cond([t1.c1 IN (1, 2, 3)]) | +---------------------------------------------------------------------------------------------------------+ 12 rows in set (0.008 sec)修改变量,仅选择 1 个 range 做存储层估行。
obclient> SET range_index_dive_limit = 1; Query OK, 0 rows affected (0.001 sec)查看执行计划,发现仅选择了第三个 range (3, MIN; 3, MAX) 做存储层估行,估行结果为
30 * 3 = 90。obclient> EXPLAIN SELECT c1 FROM t1 WHERE c1 in (1,2,3); +---------------------------------------------------------------------------------------------------------+ | Query Plan | +---------------------------------------------------------------------------------------------------------+ | ================================================== | | |ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)| | | -------------------------------------------------- | | |0 |TABLE RANGE SCAN|t1(i1)|90 |12 | | | ================================================== | | Outputs & filters: | | ------------------------------------- | | 0 - output([t1.c1]), filter(nil), rowset=256 | | access([t1.c1]), partitions(p0) | | is_index_back=false, is_global_index=false, | | range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX), (2,MIN ; 2,MAX), (3,MIN ; 3,MAX), | | range_cond([t1.c1 IN (1, 2, 3)]) | +---------------------------------------------------------------------------------------------------------+ 12 rows in set (0.003 sec)