【问题标题】:How to reduce Query execution time for Optimization?如何减少优化的查询执行时间?
【发布时间】:2021-07-22 15:20:46
【问题描述】:

您好,当前的查询执行时间过长,应进行哪些更改以减少执行时间?

EXPLAIN ANALYZE
SELECT  date_trunc({{period}}, wb.timestamp),
        CAST(COUNT(DISTINCT(org.id)) AS float) / CAST(COUNT(DISTINCT(wb.anonymous_id)) AS float) AS "marketing-lead conversion rate"
FROM website_prod.pages wb
FULL JOIN core_prod.organizations_organization org ON CAST(wb.timestamp AS DATE) = CAST(org.created_at AS DATE)
WHERE   NOT org.is_internal 
        AND wb.timestamp > date_trunc('month', CURRENT_DATE) - INTERVAL '1 year'
        AND org.created_at > date_trunc('month', CURRENT_DATE) - INTERVAL '1 year'
GROUP BY 1

QUERY PLAN

Sort Key: ((org.created_at)::date)
Sort Method: quicksort Memory: 608kB
-> Seq Scan on organizations_organization org (cost=0.00..259.02 rows=5080 width=19) (actual time=0.017..6.266 rows=5316 loops=1)
Filter: ((NOT is_internal) AND (created_at > (date_trunc('month'::text, (('now'::cstring)::date)::timestamp with time zone) - '1 year'::interval)))
Rows Removed by Filter: 1540
-> Materialize (cost=69882.44..71012.63 rows=226038 width=45) (actual time=541.950..849.952 rows=3917712 loops=1)
-> Sort (cost=69882.44..70447.54 rows=226038 width=45) (actual time=541.945..592.666 rows=232720 loops=1)
Sort Key: ((wb."timestamp")::date)
Sort Method: external merge Disk: 14104kB
-> Seq Scan on pages wb (cost=0.00..42826.15 rows=226038 width=45) (actual time=40.801..358.687 rows=232720 loops=1)
Filter: ("timestamp" > (date_trunc('month'::text, (('now'::cstring)::date)::timestamp with time zone) - '1 year'::interval))
Rows Removed by Filter: 72766
Planning time: 0.214 ms
Execution time: 26614.737 ms

【问题讨论】:

  • 除了格式错误之外,这似乎不是一个完整的执行计划,只是一堆顺序扫描和排序。请提供完整的平面图并保留前导空格。
  • 您知道使用FULL JOIN OUTER 加入),与您当前的WHERE 子句一起简单地将其转回INNER JOIN
  • 我建议你问一个新的问题。提供示例数据、期望的结果以及代码应该做什么的清晰解释。

标签: sql postgresql performance


【解决方案1】:

你的加入在我看来非常可疑......

  website_prod.pages wb
FULL JOIN
  core_prod.organizations_organization org
    ON CAST(wb.timestamp AS DATE) = CAST(org.created_at AS DATE)

在这种情况下,您要将wb 中的所有行与org 中的所有行连接起来,前提是它们“用于”同一日期。

因此,例如,如果在特定日期(例如,2021-04-01),有 10 条 wb 记录和 10 条 org 记录,则连接将给出所有 100 种组合。

  • 这真的是你想要的吗???

我会“期待”一些更像...的东西

  website_prod.pages wb
FULL JOIN
  core_prod.organizations_organization org
    ON  wb.some_key = org.some_key
    AND CAST(wb.timestamp AS DATE) = CAST(org.created_at AS DATE)

此外,为了使联接有效,该计划表明它必须按时间顺序对数据进行排序。

您没有具体说明存在哪些索引,但对于当前查询,您将从正在连接的列上的索引中受益...wb.timestamporg.created_at。不过,如果您按上述方式更改连接谓词,情况就会发生变化。

【讨论】:

  • wb.some_key 中的“some_key”是否意味着 wb 中的列名?在这种情况下会是 wb.timestamp 吗?
  • wb.some_key 将是wb 中的一列,是的。由于我已经强调的原因,它不会是timestamp。如果您不确定如何正确加入表格,请向我们提供两个表格的完整表格定义,或向您咨询有关这些表格的文档/支持人员。
  • 表之间没有“公共”列,正在考虑是否可以进行交叉连接?
  • 那么您可能需要先加入第三个/中间表。但是交叉连接不太可能是正确的答案。正如我所描述的,10 行交叉连接 10 行给出 100 行 - 这肯定不是你想要的???
猜你喜欢
  • 2020-02-10
  • 1970-01-01
  • 2012-11-09
  • 2023-03-03
  • 2016-01-29
  • 2021-01-25
  • 1970-01-01
相关资源
最近更新 更多