【问题标题】:Having clause vs subquery有子句与子查询
【发布时间】:2012-10-17 21:49:15
【问题描述】:

我可以通过两种方式使用聚合函数编写查询:

select team, count(min) as min_count
from table
group by team
having count(min) > 500

select * 
from (
    select team, count(min) as min_count
    from table
    group by team
) as A
where A.min_count > 500

这两种方法是否有任何性能优势,或者它们在功能上是否相同?

【问题讨论】:

  • 最重要的是:它们在语义上是否相同?
  • 您是否对它们进行了测试或查看了解释计划?
  • 可以显示查询执行计划吗?
  • 这是一个需要从一般原则上回答的问题。测量单个案例不是这里所要求的。它不能证明其他情况。
  • 您似乎遗漏了一些性能问题所需的关键信息。您要问什么具体的 DBMS?因为它归结为查看该 DBMS 中的实现。

标签: sql subquery having


【解决方案1】:

这两个版本在功能上是相同的。好吧,第二个在语法上不正确,但我假设您的意思是:

select * 
from (
    select team, count(min) as count
    from table
    group by team
) t
where count > 500

(您需要计算别名,而几个领先的数据库需要 FROM 子句中子查询的别名。)

功能相同并不意味着它们必须以相同的方式进行优化。通常有多种方法可以编写功能等效的查询。但是,特定的数据库引擎/优化器可以选择(并且经常选择)不同的优化路径。

在这种情况下,查询非常简单,以至于很难想到多个优化路径。对于这两个版本,引擎基本上必须聚合查询,然后测试过滤​​器的第二列。我个人看不出这个主题有很多变化。如果合适的话,任何体面的 SQL 引擎都应该在两种情况下都使用索引,或者两者都不使用。

因此,这个特定问题的答案是,在任何合理的数据库中,这些都应该导致相同的执行计划(即,在索引的使用、并行性的用户和聚合算法的选择中)。然而,功能相同并不意味着给定的数据库引擎将产生相同的执行计划。所以,一般的答案是“不”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2012-02-17
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多