위와 같은 상태에서 영업 지점(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 ;