서브쿼리란 무엇인지 개념과 활용을 알아보자
1. 조인과의 차이
조인과 서브쿼리는 구조적으로 차이가 있다.
조인은 A, B 두 집합이 동등한 관계인 반면 서브쿼리는 종속적 관계가 나타난다.
Select a.col1, b.col2
from A, B
where a.col1 = b.col1
조인의 결과는 조인에 성공한 만큼 나온다.
A 와 B 의 관계가 1: N 이면 N 만큼 결과가 나오고 1:1 이면 1 만큼 나온다.
조인의 한쪽은 인라인 뷰가 될수도 있다.
이때 둘의 관계는 동일하다고 했으므로 인라인 뷰에서 바깥쪽 테이블 컬럼을 사용할수가 없다.
Select a.col1, b.col2
from A, (select b.col1 from B where a.col1 = b.col) => error
where a.col1 = b.col1
반면 서브쿼리는 종속적 관계가 나타난다고 했다.
쿼리의 결과는 1 : N 관계에도 언제나 1 이다.
종속적 관계라서 서브쿼리에 A 의 컬럼을 사용할수 있다.
select a.col1
from A
where exists (select '1' from B where a.col1 = b.col1 ) => ok
스칼라서브쿼리도 동일한 성질을 갖는다. ( 결과row 가 변하지 않는다, 종속적 관계이다.)
2. 서브쿼리 역할
- 확인 : 결과 데이터가 증가하지 않는다. 감소만 할뿐 (N 이상이 되지 않는다.)
- 공급 : 주쿼리로 상수화된 결과를 공급
# 선/후 수행 서브쿼리
- 선수행 서브쿼리 : 서브쿼리 테이블이 driving, 모든 값에 엑세스.
unique 정렬 수행. 메모리에 임시 집합 구성.
- 후수행 서브쿼리 : driving 에서 조건에 만족하는 한건의 데이터에 대해
서브쿼리를 한번 수행. 만족하면 결과로 추출.
주 쿼리의 데이터 건수 만큼 반복 수행.
3. 서브쿼리 실행계획 제어
1. NL join -> Hash join
select colC, sum(colD)
from tab a
where colA in (select col
from tab b
where colB = 'X')
and colB between '20190101' and '20191010'
group by colC;
=>
1-1) 힌트
select /*+ USE_HASH(a,@SQ) */
colC, sum(colD)
from tab a
where colA in (select /*+ QB_NAME(SQ) */
col
from tab b
where colB = 'X')
and colB between '20190101' and '20191010'
group by colC;
1-2) 인덱스 사용 못하게
select colC, sum(colD)
from tab a
where trim(colA) in (select trim(col)
from tab b
where colB = 'X')
and colB between '20190101' and '20191010'
group by colC;
1-3) from 절에 풀기
select /*+ ORDERED USE_HASH(A,B) */
a.colC, sum(a.colD)
from tab a, tab b
where a.colA = b.col
and b.colB = 'X'
and a.colB between '20190101' and '20191010'
group by a.colC;
## 메인쿼리 : 서브쿼리 = 1:M 이면 데이터가 증가. => 인라인 뷰로 1:1 관계
select /*+ USE_HASH(A,B) */
a.colC, sum(a.colD)
from tab a,
( select col
from tab b
where b.colB='X'
group by col
)
where a.colA = b.col
and a.colB between '20190101' and '20191010'
group by a.colC;
2. 조인 순서 변경
- QB_NAME 힌트 => 선수행 서브쿼리
select /*+ PUSH_SUBQ(@SQ) */
colC, sum(colD)
from tab a
where colA in (select /*+ QB_NAME(SQ) */
col
from tab b
where colB = 'X')
and colB between '20190101' and '20191010'
group by colC;
- 일반 조인으로 변경
select /*+ ORDERED USE_HASH(A,B) */
a.colC, sum(a.colD)
from tab a,
( select col
from tab b
where b.colB='X'
group by col
)
where a.colA = b.col
and a.colB between '20190101' and '20191010'
group by a.colC;
'생계 > SQL' 카테고리의 다른 글
[oracle]프로시져 out 파라미터 호출하기 (0) | 2022.07.13 |
---|---|
transaction isolation level (0) | 2021.07.16 |
[oracle] 아우터 조인 outer join 제대로 이해하기 (0) | 2020.04.28 |
sql 튜닝 트레이스 (0) | 2019.10.21 |