SubQuery
- 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이 반드시 있어야 한다.(필수)