在红移中评估的顺序是啥
Posted
技术标签:
【中文标题】在红移中评估的顺序是啥【英文标题】:what is the order to be evaluated in redshift在红移中评估的顺序是什么 【发布时间】:2021-12-30 09:59:51 【问题描述】:我在Redshift
中尝试了两种类型的加入条件,首先我在join on
之后尝试了where
,第二,我在join on
之后尝试了and
。我假设where
在join
之后执行,所以在这种情况下,它必须扫描这么多行。
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)
另一方面,如下所述,and
在join
之前被限定,因此我假设在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 将循环分配行到节点,您的查询性能将受到影响(因为每个连接都需要一定量的重新分配)。
【讨论】:
以上是关于在红移中评估的顺序是啥的主要内容,如果未能解决你的问题,请参考以下文章