【问题标题】:Redshift behaving differetly for the same query written differently对于以不同方式编写的相同查询,Redshift 表现不同
【发布时间】:2019-11-04 21:10:03
【问题描述】:

我在使用 Redshift 时遇到异常行为,其中带有内部联接的基本查询刚刚停止按预期工作。

提供下面的查询,

SELECT D.asin, D.client_account_id
FROM ams.t_asin_segmentation_detail A_0
       INNER JOIN ams.t_asin_segmentation_value B
                  ON A_0.ASIN_SEGMENTATION_VALUE_ID = B.ID AND A_0.IS_DELETED = 'N' AND A_0.IS_ACTIVE = 'Y' AND
                     B.IS_DELETED = 'N' AND B.IS_ACTIVE = 'Y' AND B.ID IN (900)
       INNER JOIN ams.t_asin_segmentation_type C
                  ON B.ASIN_SEGMENTATION_TYPE_ID = C.ID AND C.IS_DELETED = 'N' AND C.IS_ACTIVE = 'Y' AND
                     C.ID = 1687 AND C.BUSINESS_UNIT_ID = 15
       INNER JOIN ams.t_asin D ON A_0.asin_id = D.ID AND D.is_active = 'Y' and D.is_deleted = 'N';    

此查询仅返回不正确的单行。它应该返回超过 1000 行。

当我以不同的方式编写相同的查询时,只需删除表别名为 D 的最后一个 JOIN 并以这种方式编写,

SELECT asin, client_account_id
FROM ams.t_asin
WHERE id IN (SELECT DISTINCT A_0.asin_id
             FROM ams.t_asin_segmentation_detail A_0
                    INNER JOIN ams.t_asin_segmentation_value B
                               ON A_0.ASIN_SEGMENTATION_VALUE_ID = B.ID AND A_0.IS_DELETED = 'N' AND
                                  A_0.IS_ACTIVE = 'Y' AND
                                  B.IS_DELETED = 'N' AND B.IS_ACTIVE = 'Y' AND B.ID IN (900)
                    INNER JOIN ams.t_asin_segmentation_type C
                               ON B.ASIN_SEGMENTATION_TYPE_ID = C.ID AND C.IS_DELETED = 'N' AND C.IS_ACTIVE = 'Y' AND
                                  C.ID = 1687 AND C.BUSINESS_UNIT_ID = 15)
  AND is_active = 'Y'
  AND is_deleted = 'N';

这将开始获取正确数量的行,而查询本身没有任何逻辑变化。

我对原始查询进行了进一步调整,只是将别名为 D 的表替换为 LEFT JOIN 的 INNER JOIN,令人惊讶的是,它开始提供正确的行数。需要注意的是,即使使用 LEFT JOIN,SELECT 语句仍会从别名为 D 的表中获取列,如下所示,

SELECT D.asin, D.client_account_id
FROM ams.t_asin_segmentation_detail A_0
       INNER JOIN ams.t_asin_segmentation_value B
                  ON A_0.ASIN_SEGMENTATION_VALUE_ID = B.ID AND A_0.IS_DELETED = 'N' AND A_0.IS_ACTIVE = 'Y' AND
                     B.IS_DELETED = 'N' AND B.IS_ACTIVE = 'Y' AND B.ID IN (900)
       INNER JOIN ams.t_asin_segmentation_type C
                  ON B.ASIN_SEGMENTATION_TYPE_ID = C.ID AND C.IS_DELETED = 'N' AND C.IS_ACTIVE = 'Y' AND
                     C.ID = 1687 AND C.BUSINESS_UNIT_ID = 15
       LEFT JOIN ams.t_asin D ON A_0.asin_id = D.ID AND D.is_active = 'Y' and D.is_deleted = 'N';

如果有人能提供发生这种情况的任何理由,我们将不胜感激。

【问题讨论】:

  • 你只有一行 A_0.asin_id = D.ID AND D.is_active = 'Y' and D.is_deleted = 'N' 和那些 D.ID, D.is_Active, D.is_deleted 进入你的 SELECT 子句,看看发生了什么。
  • @JNevill 准确地说,有 1023 行限定了连接条件而不是一行。这可以通过第二个查询来确定,我仍然有相同的条件并且只使用 WHERE IN 而不是 INNER JOIN。

标签: sql amazon-redshift


【解决方案1】:

您的查询完全不同。您的第一个查询是说所有匹配的行都具有相同的 D.asinD.client_account_id 值。这就是你得到一排的原因。

第二个查询在外部查询中没有distinct,因此它将获取所有这些行。

我不知道为什么你会认为它们在逻辑上是等价的。

【讨论】:

  • 我的错,我应该在发布查询之前删除 Distinct,我知道这会让人感到困惑。无论如何,删除 distinct 不会改变任何事情,因为数据实际上是唯一的,甚至不需要 Distinct。我已经更新了我的问题中的查询。
【解决方案2】:

通过将排序键上的编码类型从 ZSTD 更改为 RAW 解决了这个问题。仍然不完全确定这会如何导致 INNER JOIN 的行为发生变化。

这些查询中的排序键是连接中使用的所有 ID 列。

在此更改后,两个查询(INNER JOIN 和 WHERE IN)都返回相同的行。

【讨论】:

    猜你喜欢
    • 2019-11-23
    • 1970-01-01
    • 2012-05-23
    • 2019-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多