서브쿼리에 관해서 옵티마이저 동작방식과 merge no_merge 에 대해 알아보자.
쿼리를 짤 때, 작은 것부터 where 절로 row를 줄여나가면 더 빠르겠다는 생각으로 서브쿼리를 많이 이용했었다.
과연 더 빠르게 실행이 됐을까 ? 알아보자.
단순 View Merging
자주쓰는 쿼리 - 2022년 주문서의 제품 수와 거래처 조인쿼리
SELECT * FROM
(SELECT GURAECODE,GRANDTOTALSU SU FROM JUMUN_HEAD WHERE JUMUNNO LIKE '2022%') A
,(SELECT * FROM GURAE_CODE WHERE GURAECODE LIKE '6%') B
WHERE A.GURAECODE=B.GURAECODE

습관적으로 서브쿼리를 만들면서 쿼리를 짜는데, 해당 문을 수행 할 때 옵티마이저는 간단한 조건문은
다음과 같이 풀어서 실행한다.
>> 처음에 놀랬다. 당연히 안에 것부터 처리하고 row줄인상태에서 조인하는줄.. 풀어서 실행 할 줄이야.
SELECT * FROM JUMUN_HEAD A,GURAE_CODE B
WHERE A.GURAECODE = B.GURAECODE
AND A.JUMUNNO LIKE '2022%'
AND B.GURAECODE LIKE '6%'

두 쿼리 모두 옵티마이저가 Cost가 동일하게 동일한 방식으로 수행 계획을 세운다. - Bytes의 변동 Check
복합 View Merging
group by 나 distinct 연산을 포함하는 복합뷰는 인덱스 힌트를 통해서 View Merging 이 가능하다.
connect by, rownum, 집합연산자 포함한 복합 뷰는 View Merging이 가능하다.
2022년 주문서의 거래처 별 제품 수와 거래처 조인쿼리
SELECT * FROM
(SELECT GURAECODE,SUM(GRANDTOTALSU) SU FROM JUMUN_HEAD WHERE JUMUNNO LIKE '2022%' GROUP BY GURAECODE) A
,(SELECT * FROM GURAE_CODE WHERE GURAECODE LIKE '6%') B
WHERE A.GURAECODE=B.GURAECODE

group by가 추가되어 실행계획을 보면 View 가 있음을 확인할 수 있다.
>> no_merge 상태이며 이는 "서브쿼리를 해체하지 말아라 !" 로 이해하자.
이제 강제로 머지해보자.
SELECT /*+ merge(a) */* FROM
(SELECT GURAECODE,SUM(GRANDTOTALSU) SU FROM JUMUN_HEAD WHERE JUMUNNO LIKE '2022%' GROUP BY GURAECODE) A
,(SELECT * FROM GURAE_CODE WHERE GURAECODE LIKE '6%') B
WHERE A.GURAECODE=B.GURAECODE

뷰 과정이 사라지며 풀어 헤친걸 확인 할 수 있다. 이는 "서브쿼리를 해체하라 !" 로 볼 수 있다.
>> 뷰머징 시행 시 비용이 증가되면은 뷰머징을 안할 수 도 있고, 복합 뷰를 머징 시 댑분 나은 성능을 제공 하지만
위의 경우처럼 그렇지 못할 때가 있다.
실제 쿼리작성 시 실행계획이 100번대가 넘어가는 경우가 허다하다.
실행계획을 꼼꼼히 살피며, 지속적으로 index 힌트와 옵티마이저 동작방법에 대해 공부하자.
'데이터베이스 > SQL튜닝 PL-SQL' 카테고리의 다른 글
SQL 튜닝 - 실행계획 및 LIKE CONTAINS (0) | 2022.07.05 |
---|