HAVING子句是多余的吗?

fre*_*low 12 mysql sql group-by having having-clause

以下两个查询产生完全相同的结果:

select country, count(organization) as N
from ismember
group by country
having N > 50;

select * from (
  select country, count(organization) as N
  from ismember
  group by country) x
where N > 50;
Run Code Online (Sandbox Code Playgroud)

每个HAVING子句都可以用子查询和这样的WHERE子句替换吗?或者是否存在一个HAVING条款绝对必要/更强大/更有效/无论什么情况?

Eug*_*eck 10

这里有两个问题:第一个问题的答案是肯定的:HAVING-laden查询的结果集与作为子查询执行的同一查询的结果集相同,用WHERE子句修饰.

第二个问题是关于表现和表现力 - 在这里我们将大力实施.在MySQL上有一条细红线,性能开始分散:内部查询的结果集不能再保留在内存中.在这种情况下,MySQL将创建内部查询的磁盘表示,然后WHERE在其上使用选择器.如果使用该HAVING子句,则不会发生这种情况,将从结果集中删除不合格的组.

这意味着,HAVING子句的选择性越高,它具有的性能相关性就越高:考虑内部查询的一百万行的结果集,即通过HAVING子句减少到5行 - 很可能是结果集内部查询的内容不会保留在内存中,但很可能是最终结果集.

编辑

我有过一次:查询从非常均匀分布的表中选择了几个异常值(每天在一个车间的物理机器上生成的件数).我调查了因为IO负载很高.

编辑2

请记住,查询缓存用于子查询 - 恕我直言,地方开发应该更多地关注 - 因此子查询模式不会从内部查询作为缓存结果集中获益.


Ger*_*old 8

在Sql Server 2008中,两个类似的查询具有完全相同的执行计划:

在此输入图像描述

我还研究了很多由Entity Framework生成的查询(使用SS 2008),到目前为止,我从未见过带有HAVING子句的查询.使用聚合结果上的条件对查询进行分组始终会转换为带有子查询的查询.我相信ADO.Net团队知道他们正在做......