分组排序操作符:HAGR、SAGR
分类排序操作符表示对取到的数据做归并或排序的处理,而归并和排序在某些情况下又是互通的。
我们先看这些操作符出现的基本情况:如果SQL语句中存在 GROUP ,执行计划中大概率会出现这两个分组排序操作符之一(跳跃索引扫描之类的特殊情况暂不考虑)。
首先创建测试用表
CREATE TABLE T3(ID INT,ID1 VARCHAR);
INSERT INTO T3 SELECT LEVEL,LEVEL FROM DUAL CONNECT BY LEVEL < 10000;
--SEL17
EXPLAIN SELECT ID,SUM(ID1) FROM T3 GROUP BY ID;
1 #NSET2: [2, 99, 52]
2 #PRJT2: [2, 99, 52]; exp_num(2), is_atom(FALSE)
3 #HAGR2: [2, 99, 52]; grp_num(1), sfun_num(1);
4 #PRJT2: [1, 9999, 52]; exp_num(2), is_atom(FALSE)
5 #CSCN2: [1, 9999, 52]; INDEX33555450(T4)
HAGR 是最基础的分组方式,即进行 HASH AGR 操作,对于没有优化条件的分组语句,都会按这种方式进行分组,其分组原理和 HASH INNER JOIN 的方式类似:
将原表数据取出,每个数据转换成 FOLD ,发现有 FOLD 相同,且满足后续条件的数据合并为一组(类似 JOIN HASH SIZE,存在 INI 参数HAGR_HASH_SIZE)。
不难发现,如果基表数据非常庞大,HAGR 的计算量是不容忽视的,那么在满足一定条件的情况下,我们可以利用有序性走 SAGR 操作符:
创建索引
CREATE OR REPLACE INDEX I_TEST4 ON T4(ID,ID1);
--SEL18
EXPLAIN SELECT ID,SUM(ID1) FROM T4 GROUP BY ID;
1 #NSET2: [2, 99, 52]
2 #PRJT2: [2, 99, 52]; exp_num(2), is_atom(FALSE)
3 #SAGR2: [2, 99, 52]; grp_num(1), sfun_num(1)
4 #PRJT2: [1, 9999, 52]; exp_num(2), is_atom(FALSE)
5 #SSCN: [1, 9999, 52]; I_TEST4(T4)
这里出现了 SAGR 操作符,说明下层的输出是按分组列排序的,下层为 SSCN I_TEST4,而 I_TEST4 为 (ID,ID1) 组合索引,按照 ID 有序,满足SAGR条件。
SAGR 即 SORTED AGR 操作,不同于 HASH AGR,由于下层数据有序,同一分组的数据按照顺序取出即可,节省了大量的计算,但是下层数据量大时,开销依然需要注意。
大部分情况下如果 AGR 的下层输出在我们人为判断是有序的,但没有出现 SAGR 操作符,则可以判断计划存在问题。
文章
阅读量
获赞