PostgreSQL 12中对CTE的重要更改

WITH w AS NOT MATERIALIZED ( SELECT * FROM very_very_big_table ) SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref WHERE w2.key = 123; 

如今,提交已落入PostgreSQL存储库中,这使您可以控制CTE子查询的处理行为,即:您现在可以显式指示子查询是单独实现还是将其作为一个大型查询的一部分执行。


这将进入PostgreSQL 12,这很重要。 让我们看看为什么


程序员喜欢CTE,因为它可以显着提高代码的可读性。 好吧,的确,某些分析查询可以处理数十个表以及各种分组和过滤器。 要在一个大查询中编写所有这些内容,请确保获取不可读的内容。 因此,使用WITH运算符,我们依次在小的子查询(为它们指定了易于理解的名称)中描述工作的逻辑,然后产生结果。 很舒服


更准确地说,如果不是一回事, 那将非常方便:当前的PostgreSQL彼此分开执行这些子查询,具体化它们(将结果写入临时表)。 与一个无法读取的大型怪兽相比,这可能会导致严重的减速。 特别是如果CTE子查询返回数百万行。


但是,在某些情况下,这样的独立执行会产生好处:当更好地单独执行复杂请求的一部分时,存在这样的优化技巧,但postgres不能独自理解这一点。 然后,我们在CTE子查询中删除此部分。


通常情况是不同的,这就是为什么Postgres 12进行一次提交时会添加关键字MATERIALIZEDNOT MATERIALIZED ,它们分别表示要实现查询还是内联。


此外,默认行为已更改。 现在,如果CTE子查询的结果使用一次,它将默认内联。 否则,它将像以前一样实现。

Source: https://habr.com/ru/post/zh-CN440576/


All Articles