PostgreSQL CTE 的一般并行性

Posted

技术标签:

【中文标题】PostgreSQL CTE 的一般并行性【英文标题】:General parallelism with PostgreSQL CTEs 【发布时间】:2019-10-18 00:57:01 【问题描述】:

我正在处理一些大数据,因此有必要在我的查询中制定并行计划。我也很喜欢使用 CTE 来表达我的查询,但是按照 PostgreSQL 的文档,我不太确定 CTE 是否会对并行性造成严重限制。

Here,CTE 和临时表被标记为“并行受限”,其中“并行受限”定义为

并行受限操作是不能在并行工作者中执行,但可以在使用并行查询时在领导者中执行的操作。

Here,关于 CTE 的并行限制的描述有点不同:

如果查询在顶层或 CTE 内包含数据修改操作,则不会为该查询生成并行计划。

就我而言,我没有任何数据修改操作。

如果有的话,CTE 会在多大程度上限制我的并行计划的质量?

公平地说,我在理解第一个定义的含义时遇到了一些困难。由于 CTE 可以具体化为临时表,因此我确信这种影响更加相关。第二个定义表明,CTE 并行性限制仅与数据修改操作有关。

【问题讨论】:

据我了解,CTE 不能并行计算,但这不会阻止计划者在其他地方使用并行计算。虽然我不确定也没有使用过这个功能 【参考方案1】:

使用 CTE 很好,在大多数情况下不会妨碍并行执行。

限制是 CTE 处于并行领导进程的私有进程状态,因此并行工作人员无法对其进行扫描。除此之外,PostgreSQL 会很高兴地生成一个并行计划。

所以要避免的事情可能是像这样的查询

WITH a AS (SELECT ...)
SELECT ... FROM a JOIN b ...

如果您希望连接被并行化。 CTE内部的查询可以并行(我认为),扫描b也可以并行。

为了获得最佳并行化,您可以尝试将查询重写为

SELECT ...
FROM (SELECT ...) AS a
   JOIN b ...

【讨论】:

以上是关于PostgreSQL CTE 的一般并行性的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 嵌套 CTE 和 UNION

在 PostgreSQL 中结合 CTE 和 IN

PostgreSQL递归查询示例

PostgreSQL:让 STRING_AGG 尊重 CTE 的排序

在 plpgsql(PostgreSQL 的)中,可以将 CTE 保留到外循环吗?

mybatis+postgresql WITH RECURSIVE cte as