帮你快速理解、总结文档立即下载
文档中心>云数据库 PostgreSQL>内核能力介绍>自研内核功能介绍>相关子查询并行执行(Parallel SubPlan)

相关子查询并行执行(Parallel SubPlan)

最近更新时间:2026-07-17 20:15:00

我的收藏

功能概述

原生 PostgreSQL 在遇到含相关子查询(Correlated SubPlan)的 SQL 时,会将上层查询整体标记为 parallel_unsafe,从而无法生成 Gather / Parallel Seq Scan 等并行路径。对于事实表大、子查询在每行都要计算一次的分析型 SQL,这会导致优化器只能选择单进程串行执行,浪费机器上其余的 CPU。
在云数据库 PostgreSQL 中,支持了 SubPlan 并行执行,以解决上述问题。

前提条件

PostgreSQL 18,版本 ≥ v18.4_r1.10。

使用限制

该优化仅对 SELECT 语句生效。
当子查询处于 CTE 内、或其外部作用域存在 CTE(cteList != NIL)时,此优化会自动跳过,退回主干行为。
未相关子查询(Uncorrelated InitPlan)不进入该优化路径。
该功能默认关闭,需要 USER 会话级别打开,重启后回到默认。
仅支持内核版本 v18.4_r1.10 及以上的云数据库 PostgreSQL 实例,如您需要,请 升级小版本升级大版本

参数说明

参数名
类型
默认值
上下文
说明
tencentdb_enable_subplan_parallel
bool
off
USERSET
是否允许含相关 SubPlan 的查询生成并行计划。可通过 pg_settings 查看,SET/RESET 修改。

启用方法

会话内启用:
SET tencentdb_enable_subplan_parallel = on;
或写入 postgresql.conf 使其对所有会话生效:
tencentdb_enable_subplan_parallel = on

使用示例

准备两张小表演示计划形态:
CREATE TABLE psp_t1 (a int, b int);
CREATE TABLE psp_t2 (a int, b int);
INSERT INTO psp_t1 SELECT g, g % 10 FROM generate_series(1, 100) g;
INSERT INTO psp_t2 SELECT g, g % 10 FROM generate_series(1, 100) g;
ALTER TABLE psp_t1 SET (parallel_workers = 2);
ANALYZE psp_t1; ANALYZE psp_t2;

SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = 0;
SET max_parallel_workers_per_gather = 2;

基线(未启用)

SET tencentdb_enable_subplan_parallel = off;

EXPLAIN (COSTS OFF)
SELECT count(*)
FROM psp_t1
WHERE b > (SELECT avg(b) FROM psp_t2 WHERE psp_t2.a = psp_t1.a);
计划形态:
Aggregate
-> Seq Scan on psp_t1
Filter: ((b)::numeric > (SubPlan 1))
SubPlan 1
-> Aggregate
-> Seq Scan on psp_t2
Filter: (a = psp_t1.a)
外层是串行 Seq Scan,SubPlan 每行触发一次。

启用后(相关子查询走并行)

SET tencentdb_enable_subplan_parallel = on;

EXPLAIN (COSTS OFF)
SELECT count(*)
FROM psp_t1
WHERE b > (SELECT avg(b) FROM psp_t2 WHERE psp_t2.a = psp_t1.a);
计划形态:
Finalize Aggregate
-> Gather
Workers Planned: 2
-> Partial Aggregate
-> Parallel Seq Scan on psp_t1
Filter: ((b)::numeric > (SubPlan 1))
SubPlan 1
-> Aggregate
-> Seq Scan on psp_t2
Filter: (a = psp_t1.a)
外层升级为 Parallel Seq Scan + Gather,每个 worker 独立评估相关 SubPlan。