[강정식의 오라클 이야기] 스칼라 서브쿼리에서 2 Depth 해결방안 5 3 15,071

by 강정식 [강정식] 스칼라 서브쿼리 2Depth WITH Scalar Subquery [2007.08.31 20:41:05]


출처 - DB Guide(http://www.dbguide.net)



WITH Clause 의 활용

<개념>

with clause 는 Oracle 9i 에서 추가된 기능으로 동일한 SQL 구문을 매크로와 유사한
개념으로 사용함으로써 SQL 을 간단하게 작성하 하며 performance 향상에도 도움을
주도록 고안되어 있습니다.

동일한 SQL 부분은 임시 테이블을 생성할 것인지 아니면 인라인뷰와 조인등으로 처리할
것인지 옵티마이저가 판단하여 실행계획이 수립되게 됩니다.



Scalar Subquery 는 함수처럼 사용할 수 있으나 제약조건중 하나가 인라인 뷰가
중첩되어 있을때 메인쿼리의 조건이 스칼라 서브쿼리 안쪽의 인라인뷰 쪽으로 파고드는
View Merging 이 일어나지 않는 다는 점입니다.

SELECT DEPTNO,
(SELECT COUNT(*) -- 1 레벨
FROM (SELECT DEPTNO
FROM DEPT C -- 2 레벨
WHERE A.DEPTNO = C.DEPTNO
GROUP BY DEPTNO) B,
EMP E
WHERE E.DEPTNO = B.DEPTNO) CNT
FROM DEPT A;

ERROR at line 4:
ORA-00904: "A"."DEPTNO": invalid identifier

쿼리를 수행하면 위와 같이 에러가 나며 원인은 메인쿼리의 조건인 A.DEPTNO 가
2레벨의 중첩된 인라인뷰 안으로 파고들지 못하기 때문
입니다.

따라서 위의 쿼리를 with 구문을 사용하여 변경해 보면 다음과 같습니다.

SELECT DEPTNO,
(WITH DEPT_TEST AS (SELECT DEPTNO
FROM DEPT
GROUP BY DEPTNO)
SELECT COUNT(*)
FROM DEPT_TEST B,
EMP E
WHERE B.DEPTNO = E.DEPTNO
AND A.DEPTNO = B.DEPTNO) CNT
FROM DEPT A;

Execution Plan
--------------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 NESTED LOOPS
3 2 VIEW
4 3 SORT (GROUP BY)
5 4 INDEX (UNIQUE SCAN) OF ’PK_DEPT’ (UNIQUE)
6 2 INDEX (RANGE SCAN) OF ’IX_EMP_DEPTNO’ (NON-UNIQUE)
7 0 TABLE ACCESS (FULL) OF ’DEPT’

DEPT 를 FULL SCAN 하면서 DEPTNO 를 WITH 구문의 DEPT_TEST 로 전달하도록
View가 merging 되어 PK_DEPT 인덱스 Unique Scan 하는 것을 볼 수 있습니다.
DEPT_TEST 를 인라인뷰로 놓고 치환하면 에러가 발생하는 쿼리랑 동일하며
인라인뷰 안에 메인쿼리의 컬럼으로 조인하지 않고 바깥에서 조인하여
안으로 머지할 수 있도록 한 것이 차이점입니다.

SQL 문장 하나로 로직처리를 하고 싶으나 scalar subquery의 제약 조건 때문에
사용자 함수를 따로 작성하는 번거로움을 피하고 싶을 때 활용 가능 합니다.

by 웅 [2007.09.02 02:03:17]
오~ 중첩된 인란인뷰에서의 제약이 이런식으로처리 될 수 있군요. 감동!! 낼 함 해봐야겠네요.~~^^

by 이남규 [2007.11.09 18:13:28]
이것때문에 오늘고생하다가 도저히 안돼서 쿼리 두번날려서 해결....젠장........ㅠㅠ

by 장태길 [2008.07.17 16:52:05]
멋져부러 ㅇ.ㅇ
정식이 화이팅 !!
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입