Redshift:连接到由表中的 SELECT * 组成的子查询/CTE 相当于连接表本身,还是性能下降?
Posted
技术标签:
【中文标题】Redshift:连接到由表中的 SELECT * 组成的子查询/CTE 相当于连接表本身,还是性能下降?【英文标题】:Redshift: is a join to a subquery/CTE consisting of SELECT * from a table equivalent to joining the table itself, or a performance hit? 【发布时间】:2020-07-21 21:52:41 【问题描述】:在 Redshift 上,如果连接中使用的 CTE/子查询从源表执行 SELECT *
,与仅引用和直接连接到源表的代码相比,它是否会导致性能下降?也就是这段代码在性能上有没有区别:
WITH cte_source_2 AS (SELECT * FROM source_2)
SELECT
s1.field_1, s2.field_2
FROM
source_1 AS s1
LEFT JOIN
cte_source_2 AS s2
ON
s1.key_field = s2.key_field
还有这段代码:
SELECT
s1.field_1, s2.field_2
FROM
source_1 AS s1
LEFT JOIN
source_2 AS s2
ON
s1.key_field = s2.key_field
我认为不会,查询优化器会将第一个版本减少到第二个版本,但会得到相互矛盾的结果(我认为主要是由于缓存)。
表达这个问题的另一种方式是,除了 CTE,特别是在 Redshift 上,这样做:
SELECT
.....
FROM
(SELECT * FROM source_1) AS s1
LEFT JOIN
.......
执行同样的操作:
SELECT
.....
FROM
source_1 AS s1
LEFT JOIN
.......
很遗憾,我无法获得任何分析信息。谢谢!
【问题讨论】:
【参考方案1】:在 Redshift 上,cte 非常方便,但查询仍解析为子选择。 见https://docs.aws.amazon.com/redshift/latest/dg/r_WITH_clause.html第二段
因此,您是正确的。无论哪种方式,性能都是一样的。
cte 被解析为临时表的 postgres 上不是这种情况。见https://www.postgresql.org/docs/current/queries-with.html第一段
【讨论】:
+1 这肯定有助于我一直试图弄清楚的另一个领域,即 Redshift 上的 CTE 与子查询性能 - 感谢您的回答,我现在知道那里没有区别。还要欣赏 postgres 的对比,因为我们也在工作中使用它,我现在知道在该平台上要避免的陷阱。但我想要得到的是,使用像FROM (SELECT * FROM source_2)
这样的子查询会解析为与FROM source_2
相同吗?我也会更新问题以表明这一点。以上是关于Redshift:连接到由表中的 SELECT * 组成的子查询/CTE 相当于连接表本身,还是性能下降?的主要内容,如果未能解决你的问题,请参考以下文章
无法从 lambda 中的 python 连接到 aws redshift
如何将 Cloud9 (python) 连接到 VPC 中的 Redshift?