跳转到主内容
极星编程网:以代码为星,赴技术山海!

SQL 函数的 PARALLEL SAFE 与并行查询兼容声明规范

PostgreSQL 中的 PARALLEL SAFE 是一个函数属性声明,用于明确告知查询规划器:该函数在并行执行上下文中是安全的,可以被下推到并行工作进程(worker)中执行。它不是“开启并行”的开关,而是“允许并行”的前提条件之一。 PARALLEL SAFE 的作用与意义 当 PostgreSQL 启动并行查询(如并行顺序扫描、并行聚合等)时,规划器会检查涉及的函数是否标记为 PARALLEL SAFE 。若函数未声明或声明为 PARALLEL RESTRICTED / PARALLEL UNSAFE ,则整个并行计划可能被降级为串行执行,或相关计算被迫保留在主进程(leader)中完成,削弱并行收益。 注意: PARALLEL SAFE 不代表函数一定会被并行调用 ,它只是移除了并行执行的障碍;是否真正并行,还取决于查询结构、成本估算、
max_parallel_workers_per_gather
设置及系统资源等。 三种并行兼容性级别对比 PostgreSQL 定义了三个函数并行安全性级别,必须显式指定(默认为 PARALLEL RESTRICTED ): PARALLEL SAFE :函数不访问共享状态(如序列、临时表、客户端连接信息)、不修改数据库、不依赖会话级变量(如
current_user
、
session_user
)、不调用非 SAFE 函数。可安全地在任意 worker 进程中多次执行。 PARALLEL RESTRICTED :函数可在 leader 进程中执行,但不能下推至 worker(例如依赖
pg_backend_pid()
、
clock_timestamp()
或写入临时表)。这是用户自定义函数的默认级别。 PARALLEL UNSAFE :函数存在明显副作用或状态依赖(如修改全局变量、调用
dblink
、执行 DML),禁止在并行上下文中调用,否则可能导致错误或数据不一致。 如何正确声明 PARALLEL SAFE 在创建函数时,通过
PARALLEL
子句显式指定: CREATE OR REPLACE FUNCTION my_add(a int, b int)RETURNS int AS $$ SELECT a + b; $$LANGUAGE SQLPARALLEL SAFE; 关键注意事项: 所有被该函数直接或间接调用的其他函数,也必须是 PARALLEL SAFE ,否则声明无效,建表时会报错。 函数体中不可出现:
NEXTVAL
/
CURRVAL
(序列)、
txid_current()
、
pg_snapshot_xmin()
、
set_config()
、对临时表的读写、PL/pgSQL 的
GET DIAGNOSTICS
等。 纯计算类函数(如字符串处理、数学运算、JSON 解析)通常天然适合标记为 PARALLEL SAFE ;含 I/O、状态变更、事务/会话依赖的操作需谨慎评估。 验证与调试技巧 可通过系统视图确认函数的并行属性: SELECT proname, proparallelFROM pg_procWHERE proname = 'my_add'; 返回值含义:
s
=SAFE,
r
=RESTRICTED,
u
=UNSAFE。 启用并行查询后,使用
EXPLAIN (ANALYZE, VERBOSE)
查看执行计划,观察函数调用是否出现在
Gather
节点之下(即由 worker 执行),是判断其是否真正并行化的直接依据。

相关文章