功能描述
USE_RANGE_CACHE 和 NO_RANGE_CACHE 是一对作用于查询优化器的语句级 Hint,用于控制单条 SQL 在估算 Range 扫描行数时是否使用 Range Cache(范围统计缓存)。Range Cache 是 TDSQL Boundless 内核针对存储引擎的 SST 数据块维护的一份 Range 行数采样缓存。优化器在为 Range 扫描估算扫描行数时,可优先复用该缓存中已经采样得到的 Range 行数,从而在数据分布倾斜、直方图统计偏差较大的场景中得到更准确的代价估算和更稳定的执行计划。
是否启用 Range Cache 由系统变量
range_stat_enable_cache 控制全局开关。在该全局开关之外,可以通过下列两个 Hint 对单条 SQL 临时调整行为:USE_RANGE_CACHE:强制对该语句启用 Range Cache,即使全局开关 range_stat_enable_cache 为 OFF。NO_RANGE_CACHE:强制对该语句关闭 Range Cache,即使全局开关 range_stat_enable_cache 为 ON。适用场景:
全局已关闭 Range Cache,仅希望对个别 SQL 临时启用以验证或修复执行计划。
Range Cache 估算结果在特定场景下不符合预期,需要对个别 SQL 临时关闭,回退到默认估算路径。
配合 Statement Outline 在不修改业务 SQL 的情况下,对线上 SQL 注入 Hint 调整执行计划。
语法
USE_RANGE_CACHE 和 NO_RANGE_CACHE 是无参 Hint,作用于整条语句,不接受表名、索引名或查询块名等参数。/*+ USE_RANGE_CACHE *//*+ NO_RANGE_CACHE */
将 Hint 直接写在语句的
SELECT、UPDATE、DELETE 等关键字之后即可。SELECT、UPDATE、DELETE 语句均支持。说明:
同一条 SQL 中同时指定
USE_RANGE_CACHE 和 NO_RANGE_CACHE(或重复指定同一个 Hint)会触发冲突告警 ER_WARN_CONFLICTING_HINT,并以首先出现的 Hint 为准。使用限制
USE_RANGE_CACHE 仅在以下条件下生效,否则即使指定 Hint,Range Cache 也不会建立或使用:仅对存储引擎为 RocksDB 的用户表生效,临时表和系统表默认不参与 Range Cache。
表内存数据大小未超过
range_stat_allowed_maximum_table_size 指定的阈值。实例所在集群版本支持 Range Cache 功能。低版本集群升级到当前版本后,需确认集群协议版本满足条件。
NO_RANGE_CACHE 不受上述存储引擎限制,对任何 SQL 均可关闭 Range Cache 估算路径。示例
下例演示在表数据量较大的场景中,使用
USE_RANGE_CACHE 与 NO_RANGE_CACHE 控制单条 SQL 的 Range Cache 行为,并通过 information_schema.RANGE_CACHE 验证缓存使用情况。准备示例数据:
CREATE TABLE range_cache_demo (id INT NOT NULL,f1 INT DEFAULT NULL,f2 INT DEFAULT NULL,f3 INT DEFAULT NULL,PRIMARY KEY (id),KEY idx_f1 (f1),KEY idx_f2 (f2),KEY idx_f3 (f3, f2)) ENGINE = ROCKSDB DEFAULT CHARSET = utf8mb4;
示例 1:使用
NO_RANGE_CACHE 关闭 Range Cache在全局开关
range_stat_enable_cache = ON 的情况下,针对单条 SQL 关闭 Range Cache:SELECT /*+ NO_RANGE_CACHE */ COUNT(1)FROM range_cache_demoWHERE f1 = 10;
UPDATE 与 DELETE 语句同样支持:BEGIN;UPDATE /*+ NO_RANGE_CACHE */ range_cache_demoSET f1 = 1WHERE f1 = 10;ROLLBACK;
示例 2:使用
USE_RANGE_CACHE 强制启用 Range Cache在全局开关已关闭的情况下,针对单条 SQL 强制启用 Range Cache:
SET GLOBAL range_stat_enable_cache = OFF;SELECT /*+ USE_RANGE_CACHE */ COUNT(1)FROM range_cache_demoWHERE f1 = 10;SET GLOBAL range_stat_enable_cache = ON;
示例 3:开启
optimizer_trace 查看 Hint 生效细节SET optimizer_trace = 'enabled=on';SET range_stat_enable_trace_cache = ON;SELECT /*+ USE_RANGE_CACHE */ COUNT(1)FROM range_cache_demoWHERE f1 = 10;SELECT * FROM information_schema.optimizer_trace\\G
optimizer_trace 输出中可以看到 Range Cache 的估算细节,用于确认 Hint 是否被采纳以及具体的估算行数。注意:
USE_RANGE_CACHE 与 NO_RANGE_CACHE 仅影响 Range 扫描行数估算阶段的代价计算路径,不会改变实际的数据扫描算子,也不会跳过权限校验、事务可见性等正常执行流程。当 Hint 与表的实际情况冲突(例如表非 RocksDB 引擎、表大小超过
range_stat_allowed_maximum_table_size)时,USE_RANGE_CACHE 将自动失效,回退到默认估算路径,不会产生执行错误。不建议无差别在所有 SQL 上添加 Hint。仅在已确认默认估算路径产生不合理执行计划,且通过 Hint 验证可获得更优计划时,才使用 Range Cache 相关 Hint。