首页 > 解决方案 > RedShift:需要帮助优化子查询 WHERE IN (SELECT *)

问题描述

我对 RedShift 有下一个查询:

SELECT contributor_user_id,
            device_id_source,
            device_os,
            device_model,
            device_design,
            device_serial,
            device_carrier,
            device_os_version,
            device_manufacturer,
            device_current_app_build,
            device_current_app_version
    FROM all_values
    WHERE all_values.device_id_source :: VARCHAR NOT IN (SELECT device_id_source FROM table WHERE device_id_source IS NOT NULL)
            AND all_values.device_os :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_os IS NOT NULL)
            AND all_values.device_model :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_model IS NOT NULL)
            AND all_values.device_design :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_design IS NOT NULL)
            AND all_values.device_serial :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_serial IS NOT NULL)
            AND all_values.device_carrier :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_carrier IS NOT NULL)
            AND all_values.device_os_version :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_os_version IS NOT NULL)
            AND all_values.device_manufacturer :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_manufacturer IS NOT NULL)
            AND all_values.device_current_app_build :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_current_app_build IS NOT NULL)
            AND all_values.device_current_app_version :: VARCHAR NOT IN (SELECT device_os FROM table WHERE device_current_app_version IS NOT NULL)
  )

据我所知,WHERE IN (SELECT) 的工作速度比“JOIN”慢,并且子查询中有许多相同的请求,我认为这不好。但是我是 SQL 的新手,我不知道如何用 JOIN 重写上面的代码。你能帮助我了解知识吗?

谢谢!

标签: amazon-web-servicesamazon-redshift

解决方案


“WHERE NOT IN (SELECT ...”可能非常昂贵,因为列表可能很长并且需要进行大量比较才能确定该值是否不在列表中。执行此操作的成本稍低一些的方法是使用“ WHERE NOT EXISTS (SELECT ..." 这在内部更像是一个 JOIN 结构,但对于您的情况可能还不够快。

请注意,这些只是基于您的 SQL 和过去经验的猜测。考虑到查询的其余部分看起来多么简单,这是一个不错的选择。您可能仍想查看查询的 EXPLAIN 计划并查看成本增加最多的地方。

最好的答案是重新考虑这个查询并删除负面逻辑。如果我正在阅读这个权利,您想在contributor_user_id 中找到所有行,其中任何列出的列的“表”中的相应列值为NULL。为此,您正在使用“WHERE NOT IN”执行减法算法。我不知道你的数据模型,所以我不确定这个逻辑是否不正确。

这里的困难是我不知道你的数据和数据模型。查询将标记“table”中任何列为 NULL 的任何行,但前提是“table”中没有 device_os 重复。例如,“表”中的一行对于 device_model 为 NULL,但对于另一行中的 device_design 不为 NULL,并且具有相同的 device_os 值将不会被标记。这完全取决于您的数据中的法律模式。您的数据中具有相同 device_os 的多行是否合法?

更好的方法是将其变成一种加法算法,这可以大大减少获得所需答案所需的工作量。不了解数据和所需的逻辑,我不可能提出解决方案。示例数据和预期结果将有助于提出不同的解决方案建议。


推荐阅读