2.33 GSTU* (Grouping Sets To UNION) Grouping Sets를 UNION ALL로 변환하라

  • GSTU : Grouping Sets을 Group by + UNION ALL로 변경시키는 것을 의미함.
{code:SQLtitle= SQL 변환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
===========







































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.01610763K763K1272K (0)
6TABLE ACCESS FULLSYS_TEMP_0FD9D664F_4BB8158F110700:00:00.01610
7LOAD AS SELECT1000:00:00.01801264K264K264K (0)
8HASH GROUP BY11200:00:00.01300776K776K902K (0)
9TABLE ACCESS FULLSYS_TEMP_0FD9D664F_4BB8158F110700:00:00.01300
10VIEW13100:00:00.01820
11TABLE ACCESS FULLSYS_TEMP_0FD9D6650_4BB8158F13100:00:00.01820







































-- 변환 후
select e.department_id, NULL job_id, avg(e.salary) avg_sal
from employees e
group by e.department_id
union all
select NULL department_id, e.job_id, avg(e.salary) avg_sal
from employees e
group by e.job_id;

===========
PLAN
===========




























-

IdOperationNameStartsA-RowsA-TimeBuffersOMem1MemUsed-Mem




























-

0SELECT STATEMENT13100:00:00.0114
1UNION-ALL13100:00:00.0114
2HASH GROUP BY11200:00:00.017776K776K1666K (0)
3TABLE ACCESS FULLEMPLOYEES110700:00:00.017
4HASH GROUP BY11900:00:00.017763K763K1264K (0)
5TABLE ACCESS FULLEMPLOYEES110700:00:00.017




























-

-- 힌트적용 후
select /*+ expand_gset_to_union */
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
===========




























--

IdOperationNameStartsA-RowsA-TimeBuffersOMem1MemUsed-Mem




























--

0SELECT STATEMENT13100:00:00.0114
1VIEW13100:00:00.0114
2UNION-ALL13100:00:00.0114
3HASH GROUP BY11200:00:00.017776K776K1665K (0)
4TABLE ACCESS FULLEMPLOYEES110700:00:00.017
5HASH GROUP BY11900:00:00.017763K763K1263K (0)
6TABLE ACCESS FULLEMPLOYEES110700:00:00.017




























--


* 10053 트레이스로 확인
{code:SQL}
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature(): NULL
Registered qb: SEL$AE491F42 0xd3f6724 (SPLIT QUERY BLOCK FOR GSET-TO-UNION SEL$1; SEL$1)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature(): NULL
Registered qb: SEL$AE491F43 0xd3f365c (SPLIT QUERY BLOCK FOR GSET-TO-UNION SEL$1; SEL$1)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): qb_name=SEL$AE491F43 nbfros=1 flg=0
    fro(0): flg=5 objn=0 hint_alias="$kkqt_split_view"@"SEL$AE491F43"

중략..

---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): qb_name=SEL$21B49613 nbfros=1 flg=0
    fro(0): flg=0 objn=73948 hint_alias="E"@"SEL$1"

Registered qb: SEL$AE491F43_1 0xd9dcf90 (GROUPING SET TO UNION SEL$AE491F43)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): qb_name=SEL$AE491F43_1 nbfros=1 flg=0
    fro(0): flg=0 objn=73948 hint_alias="E"@"SEL$1"

Registered qb: SEL$AE491F43_2 0xd9daf6c (GROUPING SET TO UNION SEL$AE491F43)
---------------------
QUERY BLOCK SIGNATURE
---------------------
  signature (): qb_name=SEL$AE491F43_2 nbfros=1 flg=0
    fro(0): flg=0 objn=73948 hint_alias="E"@"SEL$1"

Registered qb: SET$D2F1856C 0xd9de4a8 (SET QUERY BLOCK SEL$AE491F43)

  • 최초 쿼리 블록명이 SEL$1이었다가 UNION에 의해 분리되고
  • 각각 분리되었던 쿼리가 최종적으로 쿼리블록인 SET$D2F1856C 가 되었다.|
    {info:title=GSTU사용시 제약사항}
    1. ROWNUM을 사용하면 기능을 사용할 수 없다.
    2. EXSIST나 NOT EXSISTS가 사용시 GSTU가 발생할 경우 SEMI/ANTI조인이 발생하지 않는다.
    > IN / NOT IN 으로 변경하면 발생가능
    {info}