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 相当于连接表本身,还是性能下降?的主要内容,如果未能解决你的问题,请参考以下文章

如何连接到 Redshift 中的私有集群?

无法从 lambda 中的 python 连接到 aws redshift

如何将 Cloud9 (python) 连接到 VPC 中的 Redshift?

如何使用堡垒主机通过 SSH 连接到 Redshift

如何使用 dplyr 和 RPostgreSQL 将 r 连接到 redshift?

尝试使用 node-redshift 从节点连接到 redshift 时超时