[Return 结果不正确]AWS Redshift(RedShift) 的 Join 语句中的限制不正确

[Return result is incorrect]Limit is incorrect in Join statement in AWS Redshift(RedShift)

运行 join语句有limit运算符时,查询结果集不正确

子查询之一:

SELECT A3.customerid FROM b1traderecords A3 WHERE A3.customerid  < 100 limit 5

customerid 
-----------
         71
         88
         11
         99
         44

  5 record(s) selected.

包含子查询的连接语句:


select A2.customerid from (SELECT A3.customerid FROM b1traderecords A3 WHERE A3.customerid  < 100 limit 5) A0, (select customerid from b3customerinfo where customerrating > 0.7) A2 where A0.customerid = A2.customerid

customerid 
-----------
         88
         44
         88
          9
         90

  5 record(s) selected.

return 值“9”不在第一个子查询结果中 因此,连接结果集似乎不正确。

这是一个错误吗?有什么建议么? 谢谢

这是预期的行为。 Redshift 是一个集群,其中不同的计算节点(和切片)独立运行。不同的数据行分布在集群的“切片”周围,因此每个都有不同的数据。当您在查询上设置这样的小限制时,无论哪个切片的数据先到达,都将通过该限制,其余部分将丢失。因此,切片之间存在“竞赛”,以先查看哪个 returns 数据。谁“获胜”可能会因各种原因而改变。

要从 LIMIT 查询中获得可预测的结果,您需要一个 ORDER BY 子句。

###################更新

在带有 LIMIT(或 TOP)的子查询中使用 order 子句,结果变为 predictable,但仍然有些不对劲。我已经重新创建了您的测试用例并尝试了这 3 个版本的查询。

select A2.i1, a1.i1 
from (select top 2 i1 from ffnr_i1 order by i1) A1 
, (select i1 from ffnr_i2 ) A2 
where A1.i1 = A2.i1 and A2.i1 > 20;

select A2.i1, a1.i1 
from (select top 2 i1 from ffnr_i1 order by i1) A1 
, (select i1 from ffnr_i2 ) A2 
where A1.i1 = A2.i1;

select A2.i1, a1.i1 
from (select top 2 i1 from ffnr_i1 order by i1) A1 
, (select i1 from ffnr_i2 ) A2 
where A2.i1 > 20;

以及运行 EXPLAIN 查询。第一个只是将子查询 where 子句移动到顶层 - 功能等效。解释计划显示 i1 > 20 通过 a1.i1 = a2.i1 要求应用于第一个子查询。它是在限制之后应用的,因此不会造成问题。

第二个例子产生了预期的结果——没有匹配。解释计划中的唯一变化是 table 中的任何一个不再有 > 20 的 where 子句。不足为奇。

第三个示例也产生了您所期望的结果 - A2 与 A1 的前 2 个值的交叉连接。解释计划中的唯一区别是这需要嵌套循环连接,并且现在首先评估 A1。

几乎可以说它采用了不包括匹配值的 LIMIT、连接列上的 WHERE 原因以及另一个 table 上的隐含 WHERE 子句。在这种情况下,查询优化器似乎正在丢弃一些东西。您应该将其作为潜在问题/错误提交给 AWS。

我用现代连接语法重写了查询,看看这是否有助于优化器,但没有成功。我还向 A1 添加了更多值(25、26、27、35、36、37),以防在 LIMIT 之前应用 WHERE 条件,但这也没有改变问题。

除非有人看到我遗漏的东西,否则我认为这可能是 Redshift 优化器错误。