【问题标题】:Why doesn't Redshift support the DOES EXIST correlated sub-query?为什么 Redshift 不支持 DOES EXIST 相关子查询?
【发布时间】:2023-03-03 21:34:01
【问题描述】:

众所周知,RedShift 有一组相关的子查询,它可以去相关,从而使查询运行得更快。

为什么 Redshift 不能去关联常见的 DOES NOT EXIST 子查询?例如,下面的查询基本上是:

SELECT ProductID,
       ProductName
FROM   Products p
WHERE  NOT EXISTS (SELECT *
                   FROM   [Order Details] od
                   WHERE  p.ProductId = od.ProductId) 

有人能解释一下为什么 Redshift 不能去关联这个查询吗?

【问题讨论】:

    标签: sql amazon-redshift


    【解决方案1】:

    我不知道为什么会做出这个决定,但这可能是因为效率。执行NOT EXISTS 意味着数据库必须扫描整个子查询以查找不存在的记录。这是非常低效的,应该尽可能避免——尤其是在处理大数据时。

    我注意到您正在从Orders 检索所有列,其中只需要ProductId。鉴于 Redshift 是一个列式数据库,选择所需的最小列数会更有效。

    您似乎正在尝试查找任何订单上不存在的产品,因此请尝试:

    SELECT
      ProductID,
      ProductName
    FROM
      Products
    WHERE
      ProductID NOT IN (SELECT DISTINCT ProductId from Orders)
    

    在英语中,这表示“选择任何不在订单上的产品”。

    【讨论】:

    • 嗯,一定是有原因的。您的查询是 O(n),因为查询是不相关的。但是亚马逊明确提到他们不支持我提到的查询,当它应该是微不足道的转换时。
    【解决方案2】:

    我在 RedShift documentation 中没有看到任何排除这种情况的东西。但是,它很容易表达为LEFT JOIN

    SELECT p.*
    FROM Products p LEFT JOIN
         [Order Details] od
         ON p.ProductId = od.ProductId
    WHERE od.ProductId IS NULL;
    

    至于为什么亚马逊选择特定功能,您必须询问他们的开发人员或营销人员。

    【讨论】:

    • 我对为什么感兴趣。看起来像亚马逊这样的蒙古人可以负担得起开发这种奢侈品。
    【解决方案3】:

    Redshift 不是在 Amazon 开发的,而是被收购以换取对 ParAccel 的投资(因为被其他人收购)。 ParAccel 显然急需现金,于是将家里的白银卖给了亚马逊。

    Redshift 是 ParAccel 在投资时提供的数据库的一个子集(假定是其中的大部分,但从未明确定义)。亚马逊在这笔交易中没有聘请任何工程师 - 只是代码。

    在 Redshift 的早期,我们只看到产品的细微变化。很明显,他们正在努力安全地做出深刻的改变。他们现在拥有一支扎实的工程团队,拥有丰富的代码知识,并且改进正在以不错的速度推出。

    所有这些实际上都是一种冗长的说法,即数据库引擎是一个非常复杂且昂贵的软件。亚马逊是出了名的,呃,“吝啬”,我认为建立这个团队/经验的成本是我们没有(也不会)看到产品降价的原因。

    Curt Monash 说:
    "规则 1: 开发一个好的 DBMS 需要 5-7 年和数千万美元。如果事情进展顺利的话。
    规则 2: 你不是规则 1 的例外情况。”
    http://www.dbms2.com/2013/03/18/dbms-development-marklogic-hadoop/

    【讨论】:

      【解决方案4】:

      AWS Redshift 支持此功能。可以在on the AWS Redshift page here 找到文档。以下解释摘自上述链接。

      语法是:

      [ NOT ] EXISTS (table_subquery)

      地点:

      • EXISTS 当 table_subquery 返回至少一行时为真。
      • NOT EXISTS 当 table_subquery 没有返回任何行时为真。
      • table_subquery 一个子查询,计算结果为包含一列或多列和一列或多行的表。

      例子:

      select dateid from date
      where exists (
      select 1 from sales
      where date.dateid = sales.dateid
      )
      order by dateid;
      
      dateid
      --------
      1827
      1828
      1829
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 2015-05-09
        • 2021-07-24
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        相关资源
        最近更新 更多