考虑使用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:
如果t2
和t1
是无法存储在内存中的大表,是否会将它们写入磁盘,从而使查询变慢?
问题3:
大型表是否应避免这种查询?
答案 0 :(得分:2)
答案:
是的。在PostgreSQL v11之前,CTE在PostgreSQL中得以实现。这会在v12中大声疾呼,从您的查询中的该版本开始,效果可能会更好。
您可以EXPLAIN
查询以确认这一点。
是。
是。
答案 1 :(得分:-4)
否。实际上,您可以添加更多的cte,而不在底部的select中使用它们,并且它们无效。查询优化器将它们变成可能的最高效联接,并一起执行所有联接。因此,CTE比临时表更好,更快。
这可能是临时表的问题,但对于CTE来说没有问题。 CTE只是表示数据的表达式,直到优化器知道您如何选择它们时,它们才会被调用。
不。实际上,如果表很大,这是代替诱惑表的方法。无论如何,如果您设置了正确的索引,则表大小无关紧要。 CTE做到了这一点,因此您不必处理稍后将在查询中被过滤掉的记录。