【问题标题】:How can I write this postgres query in Amazon redshift such that it is as optimized as it was in postgres?如何在 Amazon redshift 中编写此 postgres 查询,使其与在 postgres 中一样优化?
【发布时间】:2016-07-07 03:49:05
【问题描述】:

这是我在 postgres 中使用的原始查询 -

SELECT a.id,
    (SELECT val
       FROM database.detail x
      WHERE name = 'blablah'
        AND x.id = b.id) AS myGroup,
    c.username,
    a.someCode,
    a.timeTaken,
    a.date ::timestamp WITH time ZONE AT time ZONE 'PST' AS date,
    SUM (CASE WHEN (b.name = 'name1') THEN b.val ::INTEGER ELSE 0 END ) AS name11,
    SUM (CASE WHEN (b.name = 'name2') THEN b.val ::INTEGER ELSE 0 END ) AS name12
FROM
    database.myTable a,
    database.detail b,
    database.client c
WHERE
    a.id = b.id
    AND a.c_id = c.c_id
    AND a.date > current_date - interval '2 weeks'
GROUP BY 1, 2, 3, 4, 5, 6

以下是我如何将此查询转换为 Amazon redshift 查询。

SELECT a.id,
    b.val AS myGroup,
    c.username,
    a.someCode,
    a.timeTaken,
    convert_timezone('PST', a.date) AS date,
    SUM (CASE WHEN (b.name = 'name1') THEN b.val ::INTEGER ELSE 0 END ) AS name11,
    SUM (CASE WHEN (b.name = 'name2') THEN b.val ::INTEGER ELSE 0 END ) AS name12
FROM
    database.myTable a,
    database.detail b,
    database.client c
WHERE
    a.id = b.id
    AND b.name = 'blablah'
    AND a.c_id = c.c_id
    AND a.date > current_date - interval '2 weeks'
GROUP BY 1, 2, 3, 4, 5, 6 LIMIT 10

CASE 语句似乎没有按照预期的方式执行,基本上 name11 和 name12 的值都为零。我的 postgres 查询为这些返回有效值,但 redshift 查询没有。

另外,这个查询非常非常慢。 Postgres 查询大约需要 150 毫秒,而这个查询需要 2 分钟。

我们怎样才能做得更好?

【问题讨论】:

    标签: sql postgresql amazon-redshift


    【解决方案1】:

    Redshift 查询优化来自于对表的集群、表设计、数据加载、数据清理和分析。

    让我回答上面列表中的一些核心接触点。 1. 确保您的表 mytable、detail、client 具有正确的 SORT_KEY、DIST_KEY 2. 确保所有加入的表都已正确分析和清理。

    这是用 Redshift 格式编写的同一 SQL 的另一个版本。

    我做了一些调整

    1. 使用“With Clause”优化集群级计算
    2. 使用正确的方式连接并确保左/右连接很重要 基于数据。
    3. 将 date_range 与子句表一起用于面向对象的类型。
    4. 在下面的主 SQL 中使用了 Group By。

    我的 Redshift SQL 版本

    /** Date Range Computation **/
    with date_range as (
        select ( current_Date - interval '2 weeks' ) as two_weeks
    ),
    /** Filter main ResultSet**/
    myGroupSet as (
        SELECT b.val AS myGroup,
               c.username,
               a.someCode,
               a.timeTaken,
               (case when (b.name == 'name1') THEN b.val::INTEGER ELSE 0 END ) as name11,
               (case when (b.name == 'name2') THEN b.val::INTEGER ELSE 0 END ) as name12
          FROM database.myTable a,
          join date_range dr on a.date > dr.two_weeks
          join database.detail b on b.id = a.id
          join database.client c on c.c_id = a.c_id
         where a.date > current_Date - interval '2 weeks'
    )
    /** Apply Aggregation **/
    select myGroup, username, someCode, timeTaken, date,
           sum(name1), sum(name2)
      from myGroupSet
      group by myGroup, username, someCode, timeTaken, date
    

    【讨论】:

    • 我收到一个错误 - 字符不存在 --- for myGroupSet as (SELECT b.val AS ....看起来它无法访问表 b?
    • 朋友,SQL 只是基于您输入的 Mock SQL。请将上下文中的 SQL 调整为您的实际表、列。我分享了 Redshift 的有效性以及如何将 ANSI SQL 转换为与 Redshift 兼容的 SQL 的想法。
    猜你喜欢
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多