본문 바로가기

카테고리 없음

오라클퀴즈(2) - 20120720

위와 같은 상태에서 영업 지점(A.BR_CD), 기준일(B.GIJUN_IL)이 WHERE 조건으로 들어왔을 때 잔액의 합계 즉, SUM(B.CUR_BAL)이 입력된 기준 금액(:ISUMBAL) 이상인 고객에 대한 리스트를 보여달라는 조건이다. 다음과 같이 SQL 문을 작성할 수 있다.


CMF_CUST(고객정보, 100만건) PK : ID_NO

WDDA_ACCT(일자별고객잔고, 1억건) PK : ACC_SEQ


SELECT A.CUST_NAME, SUM(B.CUR_BAL)

FROM CMF_CUST A, WDDA_ACCT B

WHERE A.ID_NO = B.ID_NO

AND A.BR_CD = :IBRCD AND B.GIJUN_IL = :IDATE

GROUP BY A.CUST_NAME

HAVING SUM(B.CUR_BAL) >= :ISUMBAL ;


-- Execution Plan

SORT ( GROUP BY ) >> 전체 범위의 원인

NESTED LOOPS

TABLE ACCESS ( BY ROWID ) OF 'ICMF_CUST'

INDEX ( RANGE SCAN ) OF 'ICMF_CUST_IDX1'

TABLE ACCESS ( BY ROWID ) OF 'WDDA_ACCT'

INDEX ( RANGE SCAN ) OF 'WDDA_ACCT_IDX1'


문제점

GROUP BY A.CUST_NAME 때문에 전체 범위로 처리된다. 따라서 첫 화면이 나오기까지의 수행 속도가 너무 오래 걸린다.

(힌트 : 부분범위처리로 변경하라.)



해결방안

GROUP BY를 없애야만 부분범위 처리로 풀린다 따라서 GROUP BY를 없애기 위해서 SUM(CUR_VAL) 부분을 스칼라서브쿼리로 변경한다.


SELECT A.CUST_NAME, (select SUM(B.CUR_BAL) from WDDA_ACCT B

WHERE A.ID_NO = B.ID_NO

AND B.GIJUN_IL = :IDATE) SUMBAL

FROM CMF_CUST A

WHERE A.BR_CD = :IBRCD

AND (select SUM(B.CUR_BAL) from WDDA_ACCT B

WHERE A.ID_NO = B.ID_NO

AND B.GIJUN_IL = :IDATE) >= :ISUMBAL ;