Redshift - 带OR的高效JOIN子句

时间:2016-12-11 23:57:21

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

我需要将一个巨大的表(1000万行)加入到具有OR条件的查找表(15k加行)中。类似的东西:

<script language="VBScript"> 
external.menuArguments.document.body.contenteditable="True" 
</script> 

这是因为table1可以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; cd,我想加入任何一个可用的,剩下的就是其余部分。查询计划说有一个嵌套循环,我意识到这是因为NULL条件。有没有一种干净,有效的方法来解决这个问题?我正在使用Redshift。

编辑:我正在尝试使用OR运行此功能,但它似乎没有比之前更快。

2 个答案:

答案 0 :(得分:0)

如果您有首选列,则可以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,以确保不会重新分发较大的表。

[另外,对于Redshift,1000万行并不大。只是说我们在Redshift上获得了优秀的性能,即使在查询(和加入)数百亿行的表时也没有尝试过嗤之以鼻。 ]

答案 1 :(得分:0)

做两个(左)连接怎么样?随着小查找表的性能甚至不应该太差。

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中没有值。

不需要在连接中进行空检查,但可能会稍快一些。