PLAN에 나오는 오퍼레이션 중 COUNT에 속지 말자

부분범위 처리가 되도록 유도하는 페이지 처리는 적절한 ROWNUM 처리와 Order By 절, Where 절, 인덱스 구성정보가 적절하고 테이블 간 조인 방식이 Nested Loops Join 으로 수행된다면 효율적인 수행이 가능하다. 그런데 "ROWNUM 처리를 잘하자"에서 "부분범위 처리가 불가능 예"의 경우와 같이 적절하지 못한 ROWNUM 처리를 하더라도, Where 절, 인덱스 구성정보와 Order By 절의 정렬기준이 맞으면, SORT ORDER BY 오퍼레이션이 나타나지 않고, COUNT 오퍼레이션이 보인다. 그런데 COUNT 오퍼레이션이 마치 전체 데이터 처리를 하지 않고 수행하는 것처럼 보이지만 실제는 전체 데이터를 모두 처리한 후 ROWNUM 을 수행하기 때문에 주의해야 한다.
아래의 사례를 통해 확인하여 보겠다.


...(생략)
380
WHERE a.acpt_no = b.acpt_no
AND a.acpt_no = c.acpt_no
AND b.styl_cd = 'AC01'
AND a.proc_stus IN ( 'D' , 'E' )
AND a.brof_cd LIKE TRIM( :b0 ) || '%'
AND a.acpt_dt || a.acpt_time < :b1
ORDER BY a.brof_cd DESC, ---> 인덱스 컬럼 구성순서와 매칭이 됨
a.proc_stus DESC,
a.acpt_dt DESC,
a.acpt_time DESC
) x
WHERE rnum <= :b2 AND rnum >= :b3 ---> ROWNUM 처리가 비효율
Rows        Row Source Operation
---------- ---------------------------------------------------
50          FILTER (cr=8677 pr=538 pw=0 time=1957 us)
50          VIEW (cr=8677 pr=538 pw=0 time=1955 us cost=9 size=159 card=1)
599         COUNT (cr=8677 pr=538 pw=0 time=3261348 us) ---> 전체 데이터 처리함.
599         VIEW (cr=8677 pr=538 pw=0 time=3260896 us cost=9 size=146 card=1)
599         TABLE ACCESS BY INDEX ROWID TRM150 (cr=8677 pr=538 ...)
1199        NESTED LOOPS (cr=8078 pr=538 pw=0 time=227759 us ...)
599         NESTED LOOPS (cr=6874 pr=530 pw=0 time=4307258 us ...)
2057        TABLE ACCESS BY INDEX ROWID TRD100 (cr=2147 pr=10 ...)
2057        INDEX RANGE SCAN DESCENDING IX_TRD100_01 (cr=167 pr=0 ...)
599         TABLE ACCESS BY INDEX ROWID TRM100 (cr=4727 pr=520 ...)
599         INDEX UNIQUE SCAN IX_TRM100_02 (cr=4128 pr=7 pw=0 time=56539 ...)

앞의 트레이스 결과를 보면 ROWNUM 조건으로 범위 조회하여 비효율적으로 처리되고 있다. 하지만 Where 절의 인덱스 구성정보와 Order By 절이 적절히 구성되어 있어 SORT ORDER BY 오퍼레이션이 아닌, COUNT 오퍼레이션이 있는 것을 확인할 수 있다. 그러나 COUNT 는 COUNT STOPKEY 와는 다르게 전체 데이터를 모두 처리 후 COUNT 를 수행하기 때문에 실행계획만 확인하고 페이지 처리를 적용하면, 비효율적인 수행이 되기 때문에 주의해야 한다. 이를 효율적인 페이지 처리를 하기 위해서는 앞에서 "ROWNUM 처리를 잘하자"에서 설명했듯이 Rnum을 치환하기 전에 :B3 값에 해당하는 데이터만 가져오도록 ROWNUM 조건을 추가하여 성능을 개선해야 한다.