2.32 GSTT* (Group Sets Using Temp Table) Grouping Sets 사용시 Temp 테이블에 적재후 이를 반복해서 사용하라

  • GSTT : Grouping Set을 이용할 때 같은 테이블이 반복적으로 사용될 경우 필요한 항목만 Temp 테이블에 저장하여 반복작업에 사용하게 된다.
{code:SQLtitle= Grouping Sets예제borderStyle=solid}
select e.department_id, e.job_id, avg(e.salary) avg_sal
from employees e
group by grouping sets(e.department_id, e.job_id);

============
Plan Table
============







































IdOperationNameStartsA-RowsA-TimeBuffersReadsWritesOMem1MemUsed-Mem







































0SELECT STATEMENT13100:00:00.014633
1TEMP TABLE TRANSFORMATION13100:00:00.014633
2LOAD AS SELECT1000:00:00.011101264K264K264K (0)
3TABLE ACCESS FULLEMPLOYEES110700:00:00.01700
4LOAD AS SELECT1000:00:00.011011264K264K264K (0)
5HASH GROUP BY11900:00:00.01610763K763K1276K (0)
6TABLE ACCESS FULLSYS_TEMP_0FD9D6644_4BB8158F110700:00:00.01610
7LOAD AS SELECT1000:00:00.01801264K264K264K (0)
8HASH GROUP BY11200:00:00.01300776K776K906K (0)
9TABLE ACCESS FULLSYS_TEMP_0FD9D6644_4BB8158F110700:00:00.01300
10VIEW13100:00:00.01820
11TABLE ACCESS FULLSYS_TEMP_0FD9D6645_4BB8158F13100:00:00.01820








































Query Block Name / Object Alias (identified by operation id):















-

1 - SEL$658826F8
2 - SEL$375F4E67
3 - SEL$375F4E67 / SYS_TBL_$1$@SEL$375F4E67
4 - SEL$6210AD40
6 - SEL$6210AD40 / SYS_TEMP_0FD9D6649_4BB8158F@SEL$6210AD40
7 - SEL$F3EE7E8E
9 - SEL$F3EE7E8E / SYS_TEMP_0FD9D6649_4BB8158F@SEL$F3EE7E8E
10 - SEL$B441CC55 / sys_view_v@SEL$658826F8
11 - SEL$B441CC55 / SYS_TEMP_0FD9D664A_4BB8158F@SEL$658826FA


* 테이블을 임시테이블로 변환하고 세번 반복사용하였다 |
| Grouping Sets의 논리적으로 풀어낸 SQL은 다음과 같다
{code:SQL|title= SQL변환 |borderStyle=solid}
with 
temp0 as 
(select /*+ materialize */ department_id c0, job_id c1, salary a0
   from employees) ,
temp1 as 
(select /*+ materialize */ NULL c0, c1, count(a0) a1, sum(a0) a0
   from temp0
  group by c1 ) ,
temp2 as 
(select /*+ materialize */ c0, NULL c1, count(a0) a1, sum(a0) a0
   from temp0
  group by c0) ,
temp3 as 
(select temp1.* from temp1
  union all
 select temp2.* from temp2  )
 select c0 department_id, c1 job_id, a0 avg_sal
   from (select c0, c1, decode(a0, 0, to_number(null), a1/a0) a0
           from temp3 );

|

실제 10053트레이스 결과에서도 위에서 풀어낸 SQL과 동일한 쿼리블록으로 변환된 것을 확인할 수 있다.
{code:SQL
title= 10053 체크borderStyle=solid}
– temp0
Copy query block qb# -1 (<unnamed>) : SELECT "SYS_TBL_$1$"."DEPARTMENT_ID", "SYS_TBL_$1$"."JOB_ID", "SYS_TBL_$1$"."SALARY" FROM "HR"."EMPLOYEES" "SYS_TBL_$1$"
Registered qb: SEL$375F4E67 0xd98bd64 (PARSER)
– temp1
Copy query block qb# -1 (<unnamed>) : SELECT /*+ */ NULL C0, C1 C1, BIN_TO_NUM(1, GROUPING(C1)) D0, COUNT(A0), SUM(A0) FROM "SYS"."SYS_TEMP_0FD9D6649_4BB8158F" GROUP BY (C1)
Registered qb: SEL$6210AD40 0xd989668 (PARSER)
– temp2
Copy query block qb# -1 (<unnamed>) : SELECT /*+ */ C0 C0, NULL C1, BIN_TO_NUM(GROUPING(C0), 1) D0, COUNT(A0), SUM(A0) FROM "SYS"."SYS_TEMP_0FD9D6649_4BB8158F" GROUP BY (C0)
Registered qb: SEL$F3EE7E8E 0xd985d14 (PARSER)
{code}

개선점

이왕 적재를 하려면 부피를 줄여서 적재하면 효율적일텐데 Oracle Transformer는 Grouping없이 적재를 하여
성능저하가 나타날 수 있다.
이럴 경우 직접 SQL을 수정하여 튜닝하여 적재량을 줄인 후 제공하는 방법이 필요함