必须用 explain analyze(加 buffers)才能暴露聚合操作的真实开销,如磁盘排序、内存溢出、哈希/流式聚合选择等;仅 explain 仅显示预估计划,无法识别实际性能瓶颈。

直接用 EXPLAIN ANALYZE 查,别只用 EXPLAIN —— 聚合操作的真实开销(排序、分组、内存使用)只有实际执行才能暴露。
PostgreSQL 中聚合查询必须加 ANALYZE 和 BUFFERS
单纯 EXPLAIN SELECT COUNT(*) FROM orders GROUP BY status; 只显示预估计划,看不到是否触发了临时磁盘排序、是否命中 work_mem、有没有 hash aggregation。真实瓶颈往往藏在这些地方。
-
EXPLAIN ANALYZE强制执行并返回实际耗时、真实行数、循环次数,能验证rows=1000是不是真只返回 1000 行,还是被优化器严重低估 - 加
BUFFERS(即EXPLAIN (ANALYZE, BUFFERS) ...)可看到 shared hit/miss、temp read/write,判断 group by 是否溢出到磁盘(出现Temp blocks written就危险) - 避免在生产库直接跑
ANALYZE大表聚合——先用EXPLAIN (ANALYZE, TIMING OFF)关掉 timing 开销,或限制LIMIT 1配合子查询测试
MySQL 8.0+ 聚合计划要看 EXPLAIN FORMAT=JSON
EXPLAIN SELECT SUM(amount), COUNT(*) FROM sales GROUP BY region; 输出太简略,看不出是 hash aggregate 还是 temp table + filesort。必须用 JSON 格式:
EXPLAIN FORMAT=JSON SELECT SUM(amount), COUNT(*) FROM sales GROUP BY region;
重点看:"group_by_operation": "HASH_GROUP_BY"(高效) vs "group_by_operation": "FILESORT_GROUP_BY"(慢,说明没走索引或 key_len 不够);以及 "estimated_rows" 和 "rows_examined_per_scan" 是否接近,差 10 倍以上说明统计信息过期,ANALYZE TABLE sales 再试。
SQL Server 聚合运算符识别:关注 Stream Aggregate 和 Hash Aggregate
图形化执行计划里,聚合节点图标上会明确标出 Stream Aggregate 或 Hash Aggregate。两者区别直接影响性能:
-
Stream Aggregate要求输入已按 group by 列排序(比如走INDEX SEEK后天然有序),快且省内存 -
Hash Aggregate自建哈希表,不依赖输入顺序,但可能内存不足时 spill 到 tempdb(看属性里的SpillLevel > 0) - 如果看到
Sort紧挨着Stream Aggregate,说明原数据无序,强制排序——这时应检查 group by 字段是否有合适索引(含排序方向)
Oracle 聚合计划里警惕 GROUP BY NOSORT 和 GROUP BY SORT
SELECT /*+ GATHER_PLAN_STATISTICS */ COUNT(*), deptno FROM emp GROUP BY deptno; 执行后查 DBMS_XPLAN.DISPLAY_CURSOR,关键看 Operation 列:
-
GROUP BY NOSORT:表示优化器确认输入已按 deptno 排序(如走INDEX RANGE SCANon deptno),跳过排序步骤 -
GROUP BY SORT:必须额外排序,即使 deptno 上有索引,也可能因索引未包含所有 select 列导致回表后乱序 - 若
GROUP BY字段上有NOT NULL约束但计划仍显示SORT,可能是统计信息不准,用DBMS_STATS.GATHER_TABLE_STATS更新
聚合查询的执行计划最易掩盖问题:预估行数偏差、内存溢出、隐式类型转换导致索引失效、group by 字段顺序与索引列顺序不一致……这些都不会在 EXPLAIN 文本里明说,得靠 ANALYZE 实际跑、看 buffer/spill/real time 才能揪出来。











