【问题标题】:Redshift - Efficient JOIN clause with ORRedshift - 使用 OR 的高效 JOIN 子句
【发布时间】:2017-04-26 19:49:18
【问题描述】:

我需要使用 OR 条件将一个巨大的表(超过 1000 万行)连接到一个查找表(超过 15k 行)。比如:

SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t2.d)
FROM table1 t1
JOIN table2 t2 ON t1.c = t2.c OR t1.d = t2.d;

这是因为 table1 可以有 cd 作为NULL,我想加入任何可用的,而忽略其余的。查询计划说有一个嵌套循环,我意识到这是因为OR 条件。有没有一种干净、有效的方法来解决这个问题?我正在使用 Redshift。

编辑:我正在尝试使用 UNION 运行它,但它似乎没有比以前更快。

【问题讨论】:

  • 可以分享一下查询计划吗?
  • 确保在不存在重复问题的情况下使用union all,因为它更快。

标签: join inner-join union nested-loops amazon-redshift


【解决方案1】:

做两个(左)连接怎么样?即使使用小型查找表,性能也不应该太差。

SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t3.d)
FROM table1 t1
LEFT JOIN table2 t2 ON t1.d = t2.d and t1.c is null
LEFT JOIN table2 t3 ON t1.c = t3.c and t1.d is null

您的原始查询仅返回与查找表中的 c 或 d 至少之一匹配的行。如果不能保证,您可能需要添加过滤器...例如 t1 中的行,其中 c 和 d 均为 null 或 table2 中不存在值。

实际上并不需要连接中的空值检查,但可能会稍微快一些。

【讨论】:

    【解决方案2】:

    如果您有喜欢的专栏,您可以NVL()(又名COALESCE())并加入其中。

    SELECT t1.a, t1.b, nvl(t1.c, t2.c), nvl(t1.d, t2.d)
    FROM table1 t1
    JOIN table2 t2 
      ON t1.c = NVL(t2.c,t2.d);
    

    我还建议您将查找表设置为DISTSTYLE ALL,以确保不会重新分配较大的表。

    [另外,1000 万行对于 Redshift 来说并不大。并不是说即使在查询(和连接)具有数千亿行的表时,我们在 Redshift 上也能获得出色的性能。 ]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多