이 글은 'SQL 튜닝의 시작' 이란 책을 읽고 내용을 정리하는 글입니다.
[ 서브쿼리 기본개념 ]
( 서브쿼리란 ? )
- where 절에 비교조건으로 사용되는 select 쿼리
( 특징 )
- 장점 : SQL 작성시에 모든 테이블을 join으로 작성하는 것보다 메인 집합을 만들고 서브쿼리를 사용하여 값을 비교하는 절차적 SQL 작성이 비교적 간편하다.
- 단점 : 하지만, join으로 처리가 가능한 SQL임에도, 서브쿼리를 남용할 경우 Optimizer가 최적화 과정에서 잘못된 Cost 계산을 하는 경우가 발생하여 DB 서버에 치명적인 성능 문제가 발생할 수 있다.
[ 서브쿼리 사용패턴 ]
ex 1 )
select *
from emp
where sal > ( select AVG (sal) from emp )
: 추출 결과가 반드시 한 건 이여야 하는 경우 ( 만약 두 건 이상 추출된다면, 에러발생 )
위같은 경우 보통 서브쿼리 먼저 수행 후 Main SQL의 컬럼값과 비교하는 형태로 수행된다.
ex 2 )
select c1, c2, c3
from SUBQUERY_T2 t2
where c2 = 'A'
AND EXISTS (
select /*+ NO_UNNEST*/
'x'
from SUBQUERY_T1 t1
where t1.c5 = t2.c2
)
: EXISTS 나 IN 연산자 ( 또는 NOT EXISTS, NOT IN ) 을 사용한 경 우로 서브쿼리의 결과가 여러 건 추출될 수 있다.
※ 실제 서브쿼리 사용시 성능 문제를 발생시키는 대부분의 유형은 (ex2) 형태이다.
- 그러므로 위와 같은 형태의 SQL 을 작성시에 서브쿼리가 사용 의도에 맞게 수행되는지 실행계획을 반드시 확인해야 한다.
( 서브쿼리의 기본적인 특성 )
TEST 1 )
select /*+ QB_NAME(B)*/ coll
from (
select level coll
from DUAL
connect by level <= 3
) a
where a.coll IN (
select /*+ QB_NAME(A)*/ coll -- 1,2,3 각각 3개씩 출력
from(
select level coll
from DUAL
connect by level <= 3
union all
select level
from DUAL
connect by level <= 3
union all
select level
from DUAL
connect by level <= 3
)
);
: 서브쿼리만 수행할 시 결과값
COL1 - 1 2 3 1 2 3 1 2 3
: 전체 SQL 수행할 시 결과값
COL1 - 1 2 3
- 서브쿼리에서 추출되는 데이터가 중복 값이 많더라도 Unique 값만 처리하므로, 서브쿼리를 조인으로 변경하는 SQL 작성시 서브쿼리의 중복된 데이터는 제거된다는 특성을 SQL에 반드시 반영해야 한다.
( 서브쿼리를 조인 (뷰) 으로 수행되도록 유도 )
TESE 2 )
select /*+ ORDERED QB_NAME(B)*/ coll
from (
select level coll
from DUAL
connect by level <= 3
) a
where a.coll IN (
select /*+ QB_NAME(A)*/ coll -- 1,2,3 각각 3개씩 출력
from (
select level coll
from DUAL
connect by level <= 3
union all
select level
from DUAL
connect by level <= 3
union all
select level
from DUAL
connect by level <= 3
)
)
: 실행계획을 살펴보게되면, VIEW 라는 오퍼레이션이 존재하여 서브쿼리가 뷰로 변경되었으며,
HASH UNIQUE 오퍼레이션을 통해 서브쿼리를 뷰로 변경시 내부적으로 중복값을 제거 (DISTINICT 처리) 하였음을 알 수 있다. [ Oracle 기준 ]
'SQL 튜닝의 시작' 카테고리의 다른 글
[ SQL ] 스칼라 서브쿼리의 특성 (0) | 2021.04.03 |
---|---|
[ SQL ] 서브쿼리를 활용한 SQL 성능개선 (0) | 2021.03.21 |
[ SQL ] 서브쿼리 동작방식 이해하기 (0) | 2021.03.07 |