MySQL查询中HAVING和WHERE有什么区别?

5
我有一个基于一些表的联接的视图(viewX):
使用WHERE时,查询被延迟,处理器使用率达到50%,最终我需要关闭mysqld.exe服务并重新启动以尝试再次解决问题。
当我使用HAVING时,查询完美地且快速地执行,我获得结果并准备好了。
查询类似于这样:
SELECT * FROM viewX WHERE column_of_view = 'foo'

SELECT * FROM viewX HAVING column_of_view = 'foo'

发生了什么?
我找到的解决方案是像这样做:
SELECT * FROM (SELECT * FROM viewX) as T WHERE column_of_view = 'foo'

SELECT * FROM (SELECT * FROM viewX) as T HAVING column_of_view = 'foo'

两个查询都可以正常工作,但是我认为这很糟糕!(从(...viewX)选择*???)


你能发布一些执行计划吗? - Thilo
我最好的猜测是,通过使用HAVING,您正在像困惑我一样困惑查询优化器,这种混淆会导致不同的执行计划(不同的连接顺序和方法),在这种情况下可能实际上是有益的(对于许多连接,子优化连接顺序的潜力巨大)。它只是更快地返回前几行,还是整个选择所有行也更快? - Thilo
如果同时指定两者会发生什么? - Thilo
视图已经有聚合了吗? - gbn
4个回答

5

1
这是正确的,但并没有解释正在发生什么。事实上,它认为不应该有任何区别。 - Thilo

1

Having被用于像sum、avg等聚合函数中,它只能在select语句中使用。Where子句在聚合条件中无效。 例如:where sum(mark) > 300 // 此为不正确的用法


0

WHERE 用于列出数据,但还没有可用的别名名称。

HAVING 在列出所有可能的行后过滤行,因此会生成别名名称。

在行内过滤行时可能会出现问题。


0

这取决于视图的定义 - HAVING子句应该仅适用于聚合查询,并且在分组之后应用。您是否查看了两个查询计划(使用EXPLAIN)?


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