Postgres 12 物化 CTE 速度更快

Chr*_*sel 11 postgresql

迁移到 Postgres 12 后,我的一个查询时间从 6 秒缩短到 7.5 分钟。我可以通过将 MATERIALIZED 添加到 CTE 表达式来解决此问题。我不明白的是,为什么新的“未实现”默认设置在本应改善情况时却变得如此糟糕。我的表有无数列,SQL 有 230 行,所以这是这个概念的超级精简版本。

6秒查询

WITH A as MATERIALIZED (SELECT * from foo where <complicated stuff>),
     B as MATERIALIZED (SELECT * from foo where <other complicated stuff>)
SELECT * from A JOIN B ON <complicated stuff>
order by a_thing 
Run Code Online (Sandbox Code Playgroud)

该查询将相对快速地执行 A 和 B,大部分时间都在最终的合并排序中。

如果我删除 MATERIALIZED,则需要 7.5 分钟,并且解释分析显示:

  • A仍然相当快
  • 在生成 B 时循环遍历每个 A 结果。每个循环都很快,但有数以万计的循环。

所以,我的问题是,哪些因素对未物化 CTE 不利?我正在寻找概念/想法,这样我就可以深入研究我的 SQL,看看是否有办法让 NOT MATERIALIZED 更好地为我工作。

我知道如果没有 SQL,这会很困难,但它大约有 230 行长。如果觉得这个问题无法回答,我们可以删除它。

解释带有和不带有具体化的链接。但不确定explain.depesz.com 会将这些保留多久。