具有大表的通用表表达式(CTE)

时间:2019-05-18 03:58:23

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

考虑使用CTE的以下格式的查询:

WITH
    t1 AS (SELECT some_data1 FROM some_table),
    t2 AS (SELECT some_data2 FROM t1)
SELECT some_data3 FROM t2;

问题1:

执行查询时,会完全建立临时表t1并将其保存在内存中,然后完全根据t2的数据来构建t1,然后根据{{1 }}可以针对SELECT运行?

问题2:

如果t2t1是无法存储在内存中的大表,是否会将它们写入磁盘,从而使查询变慢?

问题3:

大型表是否应避免这种查询?

2 个答案:

答案 0 :(得分:2)

答案:

  1. 是的。在PostgreSQL v11之前,CTE在PostgreSQL中得以实现。这会在v12中大声疾呼,从您的查询中的该版本开始,效果可能会更好。

    您可以EXPLAIN查询以确认这一点。

  2. 是。

  3. 是。

答案 1 :(得分:-4)

  1. 否。实际上,您可以添加更多的cte,而不在底部的select中使用它们,并且它们无效。查询优化器将它们变成可能的最高效联接,并一起执行所有联接。因此,CTE比临时表更好,更快。

  2. 这可能是临时表的问题,但对于CTE来说没有问题。 CTE只是表示数据的表达式,直到优化器知道您如何选择它们时,它们才会被调用。

  3. 不。实际上,如果表很大,这是代替诱惑表的方法。无论如何,如果您设置了正确的索引,则表大小无关紧要。 CTE做到了这一点,因此您不必处理稍后将在查询中被过滤掉的记录。