为何无GROUP BY的Oracle查询执行计划中出现SORT GROUP BY?
关于JSON_ARRAYAGG导致执行计划出现SORT GROUP BY的疑问
执行的SQL查询
SELECT aad.TABLE_A_ID, JSON_OBJECT( 'details' value (SELECT JSON_ARRAYAGG( JSON_OBJECT( 'domId' value aadd.TABLE_B_ID ) ) FROM V500.TABLE_B aadd WHERE aadd.TABLE_A_ID = aad.TABLE_A_ID ) ) FROM V500.TABLE_A aad WHERE aad.TABLE_A_ID = 10441355
执行计划
PLAN_TABLE_OUTPUT Plan hash value: 1590844589 ----------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 6 | 3 (0)| 00:00:01 | | 1 | SORT GROUP BY | | 1 | 12 | | | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| TABLE_B | 2 | 24 | 2 (0)| 00:00:01 | |* 3 | INDEX RANGE SCAN | XIE1TABLE_B | 2 | | 1 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN | XPKTABLE_A | 1 | 6 | 1 (0)| 00:00:01 | -----------------------------------------------------------------------------------------------------------------
我的理解与疑问
个人理解
- GROUP BY有助于识别给定TABLE_A_ID对应的TABLE_B中所有记录。
- 排序有助于提升搜索效率,因为TABLE_B可能包含大量记录。
疑问
我并不完全确定上述理解是否正确,搜索到的相关场景均涉及查询中显式使用GROUP BY,但本查询并未显式声明。仅找到一个相关示例但缺乏足够解释,希望得到建议或逻辑参考。
解答与逻辑说明
为什么会出现SORT GROUP BY?
JSON_ARRAYAGG是聚合函数,和SUM、COUNT这类函数逻辑一致——需要将同一分组下的所有行聚合为单个JSON数组。你的子查询中,WHERE aadd.TABLE_A_ID = aad.TABLE_A_ID相当于隐式按TABLE_A_ID分组,Oracle需要把匹配该ID的所有TABLE_B行聚合成一个数组,因此触发了聚合操作。
执行计划中的SORT GROUP BY是Oracle处理聚合的常规方式:先通过索引范围扫描(步骤3)找到所有匹配的TABLE_B行,再通过排序将同一分组的行集中,最终完成数组聚合。
对原有理解的修正
- 不是GROUP BY帮助识别记录,而是聚合函数依赖GROUP BY逻辑完成行聚合——这里的分组键是
TABLE_A_ID,由子查询的关联条件隐式指定。 - 排序的目的不是提升搜索效率,而是为聚合服务:聚合需要将同一分组的行放在一起处理,排序是实现分组的一种手段。Oracle也可能选择
HASH GROUP BY等其他分组方式,但数据量较小时,SORT GROUP BY通常更高效。
核心逻辑参考
Oracle的聚合函数(包括JSON系列聚合函数)在无显式GROUP BY子句时,默认将整个结果集作为一个分组。但在你的关联子查询中,每一行TABLE_A对应的子查询结果集是按TABLE_A_ID过滤后的TABLE_B行,这相当于对每个TABLE_A_ID单独做一次聚合,因此隐式触发了分组和排序操作。
内容的提问来源于stack exchange,提问作者Siddhant
相关产品推荐
相关产品推荐

