功能描述
CACHE_RESULT 是 SUBQUERY Hint 支持的一种子查询执行策略,用于标记关联子查询(correlated subquery)的结果可缓存。优化器收到该 Hint 后,会为子查询建立基于关联列的部分结果缓存(Partial Result Cache):当外层查询多次以相同的关联键调用子查询时,命中缓存直接返回结果,避免对内表的重复计算和扫描。子查询结果缓存的全局开关由系统变量
subquery_cache_enabled 控制,是否进入缓存还会受到代价阈值 subquery_cache_cost_threshold 的影响。即使 subquery_cache_enabled 为 OFF,只要 SQL 中显式指定了 CACHE_RESULT Hint,优化器仍会针对该子查询启用缓存。命中情况可通过状态变量 subquery_cache_hit 与 subquery_cache_miss 观察。适用场景:
关联子查询的关联列基数较低,外层查询多次以相同的关联键访问子查询。
子查询本身的执行代价较高(聚合、复杂过滤等),且会被反复调用。
全局未开启子查询结果缓存,仅希望对个别 SQL 临时启用。
语法
CACHE_RESULT 必须作为 SUBQUERY Hint 的策略参数出现,不能独立使用。/*+ SUBQUERY([@query_block_name] CACHE_RESULT) */
参数说明:
@query_block_name(可选):目标子查询所在查询块的名称。当省略时,Hint 内联在子查询的 SELECT 之后,作用于该子查询本身;当指定时,需要在目标子查询中通过 QB_NAME Hint 命名查询块。两种典型写法:
内联写法:将 Hint 直接写在子查询的
SELECT 关键字之后。命名查询块写法:在外层查询通过
@query_block_name 指定目标子查询。相关变量
变量名 | 类型 | 默认值 | 作用域 | 说明 |
subquery_cache_enabled | 系统变量 | OFF | Global、Session | 子查询结果缓存的全局开关。指定 CACHE_RESULT Hint 后,即使该开关为 OFF,对应子查询仍会启用缓存。 |
subquery_cache_cost_threshold | 系统变量 | 4000 | Global、Session | 启用缓存的子查询代价阈值,仅当估算代价高于该阈值时进入缓存路径。 |
subquery_cache_hit | 状态变量 | - | Global、Session | 子查询结果缓存命中次数。 |
subquery_cache_miss | 状态变量 | - | Global、Session | 子查询结果缓存未命中次数。 |
示例
下例演示在全局关闭子查询结果缓存的情况下,使用
CACHE_RESULT Hint 对单条 SQL 启用缓存。准备示例数据:
CREATE TABLE t1 (a INT, b INT, c VARCHAR(32));CREATE TABLE t2 (a INT, b INT);INSERT INTO t1 VALUES(1, 10, 'row1'), (2, 20, 'row2'), (3, 30, 'row3'),(4, 40, 'row4'), (5, 50, 'row5');INSERT INTO t2 VALUES(1, 100), (1, 110), (2, 200), (2, 210),(3, 300), (3, 310), (4, 400), (5, 500);ANALYZE TABLE t1, t2;SET subquery_cache_enabled = OFF;FLUSH STATUS;
示例 1:内联写法
EXPLAIN FORMAT=TREESELECT *FROM t1WHERE b > (SELECT /*+ SUBQUERY(CACHE_RESULT) */ AVG(b)FROM t2WHERE t2.a = t1.a);
执行计划中可观察到
Partial result cache on keys(t1.a),说明子查询已按关联列 t1.a 建立缓存。示例 2:命名查询块写法
EXPLAIN FORMAT=TREESELECT /*+ SUBQUERY(@subq1 CACHE_RESULT) */ *FROM t1WHERE b > (SELECT /*+ QB_NAME(subq1) */ AVG(b)FROM t2WHERE t2.a = t1.a);
执行后,可通过状态变量观察缓存命中情况:
SHOW STATUS LIKE 'subquery_cache%';
返回结果示例:
Variable_name Valuesubquery_cache_hit <hit count>subquery_cache_miss <miss count>
说明:
CACHE_RESULT 仅对关联子查询生效;非关联子查询会按其他子查询执行策略处理,Hint 不会建立结果缓存。CACHE_RESULT 不能与同一 SUBQUERY Hint 中互斥的策略(如 MATERIALIZATION、INTOEXISTS)冲突使用,否则 Hint 不会生效。