最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
为什么SQL查询里HAVING子句有时比WHERE子句性能更好
时间:2026-07-10 10:51:57 编辑:袖梨 来源:一聚教程网
HAVING 从不比 WHERE 性能更好,因为 WHERE 在分组前基于原始行过滤并可利用索引,而 HAVING 必须等待 GROUP BY 完成聚合计算后才执行,无法跳过中间结果。
HAVING 从不比 WHERE 性能更好——这是个常见误解,根源在于混淆了“执行阶段”和“数据量”。
WHERE 和 HAVING 的执行顺序不可逆
SQL 引擎严格按固定顺序执行:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。这意味着:
-
WHERE在分组前过滤原始行,能直接利用索引、跳过大量数据,降低后续计算开销 -
HAVING必须等GROUP BY完成、所有聚合值(如SUM()、COUNT())算出来之后才开始工作,此时数据已分组、内存中存着中间结果集 - 没有例外:哪怕你写
SELECT 1 HAVING 1=1(无GROUP BY),多数数据库(如 MySQL 5.7+、PostgreSQL)也把它当作单一分组处理,仍绕不开聚合计算流程
什么情况下会误判 “HAVING 更快”?
实际观察到的“HAVING 查询更快”,几乎都源于对比方式错误或隐藏变量干扰:
- 拿一个带
WHERE但没建索引的查询(如WHERE status = 'pending'),跟一个带HAVING且恰好命中缓存的查询比——错把缓存效应当性能优势 - 在小表(HAVING 看似“没拖慢”,就误以为它“不差”
- 把
WHERE写在GROUP BY后(语法错误)、或漏写GROUP BY导致查询失败,再换成HAVING后“能跑了”,就以为是“优化”
真正影响性能的关键不是子句名,而是数据量落点
决定速度的是「在哪一步减少多少数据」:
- 用
WHERE order_date >= '2026-01-01'过滤掉 95% 历史订单 → 分组只算最近数据 → 快 - 用
HAVING COUNT(*) > 10筛选客户 → 引擎必须先为每个客户算出完整计数 → 即使最终只留 5% 分组,前面 100% 的聚合计算已做完 → 慢 - 若业务逻辑确实需要聚合后筛选(比如“找出平均响应时间超 2 秒的接口”),那
HAVING是唯一合法路径,此时谈“优于 WHERE”无意义——它们根本不在同一层面上竞争
最常被忽略的一点:有些数据库(如 MySQL 8.0)在 HAVING 条件简单且字段有索引时,会尝试下推优化,但这属于引擎内部黑盒行为,不可依赖;而 WHERE 的索引走查是稳定、可预期、可 explain 验证的。
相关文章
- 诛仙世界云若·梦影游仙新时装怎么获得 07-29
- 检疫区最后一站灭鼠者成就如何完成 07-29
- 蚂蚁森林神奇海洋2026年1月26日答案 07-29
- 三角洲行动长弓溪谷2.2日密码是多少 07-29
- html-anything 怎么安装?Codex/Claude Code 本地 HTML 编辑器教程 07-29
- Gardenin新滤镜成就如何解锁 07-29