【问题标题】:Most effective way to use group function in another column在另一列中使用组功能的最有效方法
【发布时间】:2015-01-12 18:50:36
【问题描述】:

我有一个看起来像这样的查询:

SELECT COUNT(DISTINCT A) as a_distinct,
       COUNT(DISTINCT B) as b_distinct,
       COUNT(DISTINCT A)/COUNT(DISTINCT B) as a_b_ratio
FROM
       sometable_ab

我们可以看到这看起来非常低效,因为聚合函数运行两次,即使它们已经被计算过。我只能想到一种解决方案,将其分解为两个查询。这是唯一可能的解决方案。或者他们是可以完成的更好更有效的解决方案。我正在使用 Redshift DB,它主要使用 postgresql,但即使是 MYSQL 的解决方案也是可以接受的,因为我无法在任何数据库中有效地做到这一点。

【问题讨论】:

  • "...聚合函数运行两次..."你怎么知道的?
  • @MikeSherrill'CatRecall' 我如何知道它是如何执行的?解释计划让我感到困惑。
  • 使用EXPLAIN (ANALYZE, TIMING OFF) 在一个大表上运行所有查询变体几次,然后比较最佳执行时间以找出答案。您甚至不需要查询计划,只需要执行时间。
  • 好像 Redshift 只支持基本的EXPLAIN。没有ANALYZE。您需要另一种方法来测试执行时间。
  • 它给出了一个查询所涉及的全面成本,尽管它确实给出了一个平均的想法,我已经分析过无论我在问题中使用该方法还是在子查询中使用该方法,我总是得到相同的结果成本。

标签: mysql sql database postgresql amazon-redshift


【解决方案1】:

如果您担心性能影响,只需使用子查询:

SELECT a_distinct, b_distinct, a_distinct / b_distinct as a_b_ratio
FROM (SELECT COUNT(DISTINCT A) as a_distinct,
             COUNT(DISTINCT B) as b_distinct
      FROM sometable_ab
     ) ab

对于大多数聚合函数,这无关紧要,但 count(distinct) 可能会消耗性能。

这是 ANSI 标准 SQL,应该适用于您提到的任何数据库。

【讨论】:

  • 但这又是两个查询......我在想一些更微妙的东西可用。
  • @Sohaib 。 . .这是一个使用子查询的查询;它是 not 两个查询。在 Postgres 和(可能是 Redshift)中,子查询的使用没有任何区别。即使在实现子查询的 MySQL 中,您所谈论的也是具有两列和两行的中间结果——完全可以忽略不计。
  • @GordonLinoff:我在本地对 PostgreSQL 9.3 进行了一些快速测试。除了子查询扫描之外,这两个执行计划是相同的。
  • @MikeSherrill'CatRecall' 。 . .有趣的。这表明 Postgres 也实现了子查询。就性能而言,这与只有一行的子查询无关,但仍然很有趣。
  • @GordonLinoff 所以最后的判决?由于 Postgres 进行了优化,问题中的查询和答案中的查询将执行相同的操作?
【解决方案2】:

对于任何 RDBMS,使用子查询仍然算作 一个 查询。更重要的是,count() 永远不会返回 NULL,但如果没有找到任何行(或任何行中的给定表达式没有非空值),则返回 0。这将导致您直接进入除以零异常。用NULLIF(也是标准SQL)修复它。在这种情况下,你会得到 NULL。

SELECT *, a_distinct / NULLIF(b_distinct, 0) AS a_b_ratio
FROM (
   SELECT count(DISTINCT a) AS a_distinct
        , count(DISTINCT b) AS b_distinct
   FROM   sometable_ab
   ) sub;

【讨论】:

    猜你喜欢
    • 2018-03-22
    • 2020-07-26
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多