相关疑难解决方法(0)

从 Postgres 11 升级到 Postgres 12 使某些查询速度慢了 300 倍,可能是由于新的 CTE 处理

我的应用程序当前使用 PostgreSQL 11.6。今天,我在虚拟机上测试了 PostgreSQL 12.1,结果令人震惊:一个重要查询在版本 11(同一虚拟机)上需要 100 毫秒,现在在 Postgres 12 上只需要大约 36 秒。这慢了 300 多倍。

我怀疑 CTE 的新处理方式,即MATERIALIZED,NOT MATERIALIZED是造成这种情况的原因。

如果我将每个 CTE 更改为MATERIALIZED,查询时间将从 36 秒减少到 6 秒。明显好一些,但仍然比版本 11 慢 50 倍以上。

如果我没猜错的话,在 PostgreSQL 12 中你有两个替代选项:

  • 使用MATERIALIZEDCTE 只执行一次,但你失去了索引的好处
  • 您可以获得NOT MATERIALIZED索引的好处,但每次访问其结果时都会执行您的 CTE。

那是对的吗?

是否有任何技巧,例如返回 Postgres 11 行为的特殊设置?或者是处理此问题的唯一方法,手动评估每个 CTE 是否MATERIALIZED更好NOT MATERIALIZED

我想,很多时候并不清楚哪种方式更好。我的应用程序包含数百个 CTE,其中许多都执行表查询和昂贵的函数调用(文档中的示例,他们说这NOT MATERIALIZED更好)。

编辑: 我检查过的内容以使结果具有可比性:

  • 同一虚拟机
  • 相同且非常小的数据集
  • 相同的 postgresql.conf
  • 重新索引
  • vacuum analyze

结果EXPLAIN ANALYZE …

cte upgrade postgresql-12 postgresql-performance

6
推荐指数
1
解决办法
5446
查看次数