Having子句 vs 子查询

19

我可以用聚合函数编写两种查询:

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

这两种方法是否有性能上的优劣之分,或者它们在功能上是相同的?


1
最重要的是:它们在语义上是否相同? - usr
你能展示查询执行计划吗? - Tim Schmelter
1
这是一个需要根据一般原则回答的问题。在这里并不要求测量单个案例。这对其他案例没有任何证明作用。 - usr
@MartinSmith,我知道这两个。这不是精确的查询,只是快速编写的。我在这里不是寻求语法检查,而是要回答查询的性能问题。 - ferics2
1
您似乎省略了一些性能问题所需的关键信息。您具体在询问哪个DBMS?因为这取决于查看该DBMS中的实现。 - Martin Smith
显示剩余5条评论
1个回答

14
这两个版本在功能上是相同的。第二个版本语法上有错误,但我猜你的意思是:
select * 
from (
    select team, count(min) as count
    from table
    group by team
) t
where count > 500

您需要在计算中使用别名,而且一些主要的数据库在FROM子句中的子查询上要求使用别名。函数等效并不意味着它们一定以相同的方式进行优化。通常有多种编写查询的方法可以实现函数等效。然而,特定的数据库引擎/优化器可以选择(并经常选择)不同的优化路径。在这种情况下,查询非常简单,很难想到多种优化路径。对于两个版本,引擎基本上必须聚合查询,然后测试第二列以进行筛选。我个人看不出有太多的变化。任何合理的SQL引擎都应该在这两种情况下(或者两种情况下都不)使用索引(如果适用)。因此,对于这个具体的问题,任何合理的数据库都应该产生相同的执行计划(即使用索引、并行处理和聚合算法的选择)。然而,函数等效并不意味着给定的数据库引擎将产生相同的执行计划。所以,一般的回答是“不”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接