在红移中评估的顺序是啥

Posted

技术标签:

【中文标题】在红移中评估的顺序是啥【英文标题】:what is the order to be evaluated in redshift在红移中评估的顺序是什么 【发布时间】:2021-12-30 09:59:51 【问题描述】:

我在Redshift 中尝试了两种类型的加入条件,首先我在join on 之后尝试了where,第二,我在join on 之后尝试了and。我假设wherejoin 之后执行,所以在这种情况下,它必须扫描这么多行。

explain
select
    *
from
    table1 t
    left join table2 t2 on t.key = t2.key
where
    t.snapshot_day = to_date('2021-12-18', 'YYYY-MM-DD');

XN Hash Right Join DS_DIST_INNER  (cost=43055.58..114637511640937.91 rows=2906695 width=3169)
  Inner Dist Key: t.key
  Hash Cond: (("outer".asin)::text = ("inner".asin)::text)
  ->  XN Seq Scan on table2 t2  (cost=0.00..39874539.52 rows=3987453952 width=3038)
  ->  XN Hash  (cost=35879.65..35879.65 rows=2870373 width=131)
        ->  XN Seq Scan on table1 t (cost=0.00..35879.65 rows=2870373 width=131)
              Filter: (snapshot_day = '2021-12-18 00:00:00'::timestamp without time zone)

另一方面,如下所述,andjoin 之前被限定,因此我假设在join 中扫描的行数较少。但它返回的行数太多,消耗的成本比where子句要大

explain
select
    *
from
    table1 t
    left join table2 t2 on t.key= t2.key
and
    t.snapshot_day = to_date('2021-12-18', 'YYYY-MM-DD');

XN Hash Right Join DS_DIST_INNER  (cost=40860915.20..380935317239623.75 rows=3268873216 width=3169)
  Inner Dist Key: t.key
  Hash Cond: (("outer".key)::text = ("inner".key)::text)
  Join Filter: ("inner".snapshot_day = '2021-12-18 00:00:00'::timestamp without time zone)
  ->  XN Seq Scan on  table2 t2  (cost=0.00..39874539.52 rows=3987453952 width=3038)
  ->  XN Hash  (cost=32688732.16..32688732.16 rows=3268873216 width=131)
        ->  XN Seq Scan on table1 t  (cost=0.00..32688732.16 rows=3268873216 width=131)

它们之间有什么区别?在这种情况下我在哪里误解? 如果有人有意见或材料,请告诉我

谢谢

【问题讨论】:

【参考方案1】:

这里发生了几件事(在我的原始答案中,我错过了您正在执行外部联接,因此这是一个完整的重写)。

    WHERE 发生在 JOIN 之前(即,现实世界的数据库不使用关系代数)

    连接合并公共列上的两个结果集。查询优化器将尝试通过应用 WHERE 子句中独立于连接的任何谓词来减小这些结果集的大小。

    JOIN 子句中的条件控制两个结果集的合并方式,仅此而已。

    这是您的两个查询之间的语义差异:当您在 WHERE 子句中指定 t.snapshot_day 的谓词时,它会限制从 t 中选择的行。当您在JOIN 子句中指定它时,它控制t2 中的行是否与t 中的行匹配,t 中选择哪些行或从哪些行返回加入。

    您正在执行外部联接。

    在内连接中,当且仅当JOIN 子句中的所有条件都匹配时,两个结果集之间的行才被连接,并且只返回那些行。实际上,这将结果集限制为仅t 中满足谓词的那些行。

    然而,外部联接从外部结果集中选择 所有 行(在这种情况下,来自t 的所有行),并包括来自内部结果集中的值 iff all join条件为真。因此,您将只包含来自 t2 的数据,其中键匹配 并且 谓词适用。 对于t 中的所有其他行,您将获得空值。

    DS_DIST_INNER 可能是个问题

    与连接语义无关,但对于 Redshift 中的大型查询,重新分配行非常昂贵。为避免这种情况,您应该将所有表显式分布在连接中最频繁使用(或与涉及最多行数的连接一起使用)的列上。

    如果您不选择显式分配键,那么 Redshift 将循环分配行到节点,您的查询性能将受到影响(因为每个连接都需要一定量的重新分配)。

【讨论】:

以上是关于在红移中评估的顺序是啥的主要内容,如果未能解决你的问题,请参考以下文章

在红移中作为选择插入

在红移中插入

数据值“0”在红移中有无效格式错误

如何在红移中获取过去 X 周的数据?

如何获得最近 x 周数据的不同计数,但在红移中按周分组?

在红移中计算一年中的周数作为excel中的weeknum()