PostgreSQL子查询/ CTE是否已缓存?

时间:2018-09-18 06:41:15

标签: postgresql subquery common-table-expression query-performance

通过缓存,我的意思是是否为每个提取的行都调用了子查询?

几个例子

-- Simple query
SELECT * FROM (
    SELECT * FROM accounts
) AS subquery;

-- Subquery with function
SELECT * FROM (
    SELECT AVG(id_groups) FROM accounts
) AS subquery;

-- More messy queries
SELECT * FROM (
  SELECT id_groups, AVG(id_accounts) OVER (PARTITION BY id_groups)
  FROM accounts
) AS subquery
GROUP BY subquery.id_groups, subquery.avg;

而且

两者之间是否有区别

SELECT * FROM (
    SELECT * FROM accounts
) AS subquery;

WITH everything_about_accounts AS (
    SELECT * FROM accounts
)
SELECT * FROM everything_about_accounts;

1 个答案:

答案 0 :(得分:3)

关于FROM子句中的子查询:

对于返回的每一行,将执行子查询;在这些情况下,这毫无意义。

在您呈现的三种情况下,PostgreSQL甚至会扁平化子查询:优化器意识到子查询是不必要的,并相应地转换了查询。

在查询中使用EXPLAIN可以看到实际效果。

关于CTE:

FROM子句中的子查询不同,CTE充当优化障碍,也就是说,优化器不会尝试使其平坦化或将条件推入其中。

相反,将执行CTE并将结果实现 ,查询将对实现的结果执行 CTE扫描

再次使用EXPLAIN来查看它的运行情况。

PostgreSQL社区正在努力消除CTE始终实现的限制(或功能,因为它是一种引导优化程序的方式)。