PostgreSQL:如何在函数中并行运行查询?

Bak*_*ker 3 sql postgresql parallel-processing

我有一个简单的查询

select bod_vykonu_kod, count(1)
from cdc_s5_zdroj
group by 1
order by 1 desc;
Run Code Online (Sandbox Code Playgroud)

它应该像它应该的那样并行运行。
解释分析: https: //explain.depesz.com/s/auVt

然后,如果我将相同的查询放入函数中,它就不会并行运行。我尝试了STABLEVOLATILE,但仍然没有相似之处。我还添加了PARALLEL SAFE但没有区别。

CREATE OR REPLACE FUNCTION 
test_par () 
returns table (
t_column1 bigint,
t_column2 bigint
)

volatile
PARALLEL SAFE
AS $dbvis$

BEGIN

RETURN QUERY
select bod_vykonu_kod, count(1)
from cdc_s5_zdroj
group by 1
order by 1 desc;

END;
$dbvis$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

解释分析易失性:https://explain.depesz.com/s/glFO
解释分析稳定:https://explain.depesz.com/s/vnXO
Explain analyze stable and parallel safe: https://explain.depesz.com/s/QlKM

x86_64-pc-linux-gnu 上的 PostgreSQL 11.5,由 gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36) 编译,64 位
max_parallel_workers = 8
max_parallel_workers_per_gather = 4

我做错了什么或者函数不支持这样的并行执行吗?

Jer*_*emy 5

我对 plpgsql 函数也有同样的问题。RETURN QUERY 从未并行运行。我能找到的唯一解决方案是执行类似的操作,因为CREATE TABLE AS 使用并行处理:

CREATE OR REPLACE FUNCTION 
test_par () 
returns table (
t_column1 bigint,
t_column2 bigint
)

volatile
AS $dbvis$

BEGIN
CREATE TEMPORARY TABLE my_temp ON COMMIT DROP AS
select bod_vykonu_kod, count(1)
from cdc_s5_zdroj
group by 1
order by 1 desc;

RETURN QUERY SELECT * FROM my_temp;
DROP TABLE IF EXISTS my_temp;
END;
$dbvis$ LANGUAGE plpgsql
Run Code Online (Sandbox Code Playgroud)

这并不理想,但就我的情况而言,它仍然比不使用并行处理快得多。

更新:从 Postures 14 开始,返回查询现在将使用并行工作线程。我们不再需要使用创建表解决方法。