• Main에 종속되는 하위Query. 집합과 집합간의 연결을 통해 데이터를 추출하는 기법
  • Join의 경우는 Join되는 집합의 데이터를 추출에 사용할수 있는 반면, Sub Query는 Main Query의 결과를 추출하기 위한 상수조건 또는 체크조건으로 참여하게 된다.
  • 주종의 관계 : Sub Query가 종으로 먼저 수행된 후 Main Query의 결과를 줄여주는 역할로 참여
                       Main Query는 Sub Query의 존재와 관계없이 독자실행 가능하며, 단지 Sub Query는 범위를 줄여주는 역할.
  • 동일한 조건의 체크관계: 주종관계가 아닌 Main과 Sub가 동일한 레벨의 상태.
                       Main Query만으로 안되며, Sub Query 도 독립적 결과 를 추출할수 없다.




1. 주종관계를 가지는 Sub Query 

; Sub Query가 먼저 실행.

- 먼저 수행된다 는 것은 Sub Query가 먼저 수행되어 Main Query의 결과 추출에 참가한다는 것. 

 Main Query에 Sub Query의 조건이 상수가 되어 in 또는 = 조건으로 제공한다는 것.


Sub Query의 결과가 여러건이거나 여러건 중복이 되어 나오더라도 Sub Query의 결과를 정렬하여 Main Query 에 제공한다.
  Sub Query는 Main Query에 상수로 데이터를 제공하기 전에 데이터가 여러건이라면 Sort Unique 작업 후 제공한다.


ex>

SELECT a.code, a.name, a.deptno

   FROM tab1 a

  WHERE a.code IN ( SELECT code

                                 FROM tab2

                               WHERE gcode = '20'

                            )

; Sub Query로 범위를 줄임.

; Main Query의 상수로 데이터 제공.




2. 주종관계를 갖지 않는 Sub Query

; Main Query가 먼저 수행된 후 수행됨.


ex> 

SELECT a.code, a.name, a.deptno

   FROM tab1 a

  WHERE a.code IN ( SELECT code

                                 FROM tab2

                                WHERE deptno = a.deptno

                                    AND gcode = '20' )


; a의 deptno를 사용.

; Main Query 수행 --> Sub Query 수행 --> Main Query 수행.




3. 주종관계로 수행하는 조건

1) Sub Query 에 Main Query의 컬럼이 조건에 나오면 안됨.


2) Sub Query의 결과를 제공받는 Main Query 의 조건에 인덱스가 존재해야 한다.

   없다면 Nested loop join의 연결고리 이상으로 Full Table Scan 후 Sub Query와 연결하여 데이터를 추출할게 된다.



3) Exists를 이용한 Sub Query로의 전환

ex>

SELECT a.code, a.name, a.deptno

   FROM tab1 a

  WHERE a.code IN ( SELECT code

                                 FROM tab2

                               WHERE deptno = a.deptno

                                   AND gcode = '20'

                            )

-->


SELECT a.code, a.name, a.deptno

   FROM tab1 a

  WHERE Exists       ( SELECT code

                                 FROM tab2

                               WHERE deptno = a.deptno

                                   AND gcode = '20'

                            )



4) Not In의 성능개선


SELECT a.code, a.name

   FROM tab1 a

  WHERE a.code Not IN ( SELECT code

                                      FROM tab2

                                   WHERE gcode = a.code )

-->

SELECT a.code, a.name

   FROM tab1 a

  WHERE a.code IS NOT NULL

      AND a.code Not IN ( SELECT /*+ MERGE_AJ */

                                               deptno

                                      FROM tab2

                                   WHERE gcode = a.code 

                                        AND deptno IS NOT NULL )


; Not In을 사용하는 경우Hint를 이용하여 성능개선

; Oracle Optimizer Hint 중 /*+ MERGE_AJ */ /*+ HASH_AJ */

; 교집합의 데이터를 추출하는 것이 아니라 양쪽집합의 차집합을 추출하는 것. 

각각을 수행하여 병합에 실패한 데이터만 추출하는 Merge Anti Join이나 동시에 각각의 데이터를 추출하여 Hash Join의 실패한 데이터만 추출하는 Hash Anti Join

; 각 집합의 조건에 참여하는 부분이 Not Null이어야 한다.

; 조건에 Is Not Null이 반드시 있어야 한다.(필수)






'DBMS > 오라클기타' 카테고리의 다른 글

오라클 IMPORT  (0) 2013.05.17
Cluster  (0) 2013.05.12
view  (0) 2013.05.12
Nested Loop Join  (0) 2013.05.05
전체 범위 처리 & 부분 범위 처리  (0) 2013.05.05

+ Recent posts