繁体   English   中英

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

[英]PostgreSQL: How to run query in parallel in function?

我有一个简单的查询

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

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

然后,如果我将相同的查询放在 function 中,它就不会并行运行。 我将其作为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

解释分析易失性: 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

我做错了什么还是函数不支持这样的并行执行?

我对 plpgsql function 也有同样的问题。 返回查询从未并行运行。 我能找到的唯一解决方案是做这样的事情,因为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

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

我深入研究了代码,看看为什么RETURN QUERY不支持并行执行。

原因是它使用 cursor 以 50 个批次获取查询结果,使用 cursor 执行的查询不是并行运行的(因为可能会暂停执行)。

这是来自src/pl/plpgsql/src/pl_exec.c的 function exec_stmt_return_query中的相关代码:

exec_stmt_return_query(PLpgSQL_execstate *estate,
                       PLpgSQL_stmt_return_query *stmt)
{
[...]
    if (stmt->query != NULL)
    {
        /* static query */
        exec_run_select(estate, stmt->query, 0, &portal);
    }
[...]
    while (true)
    {
        uint64      i;

        SPI_cursor_fetch(portal, true, 50);

[...]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM