DATOR


이력집합에서 최대값 Random I/O 줄이는 방법

사이트에서 가서 컨설팅을 하다 보면 개발자들이 힘들어 하는 경우가 몇가지가 있는데 그중에 하나가 바로 아래의 CASE인 경우이다.

 

CASE1)
 주문이 발생한 고객중에서 고객이 가지고 있는 현금영수증의 마지막 값에 해당 하는  정보를 가져와라
 
인덱스01:고객번호+현금영수증일련번호
 

SELECT  /*+ ORDERED USE_NL(A B) */
        A.주문번호
       ,A.주문일시
       ,B.현금영수증일련번호
       ,현금영수증관련 속성
  FROM  주문 A
       ,현금영수증정보 B
 WHERE A.고객번호 = B.고객번호
   AND B.현금영수증일련번호 = (SELECT /*+ INDEX_DESC(B 인덱스01) */
                                      MAX(현금영수증일련번호)
                                FROM  현금영수증정보 B
                                WHERE A.고객번호 = B.고객번호
                                AND ROWNUM<=1)
   AND A.주문일시 BETWEEN SYSDATE-100 AND SYSDATE-99;

 

01.gif

 

 

PLAN을 보면 가장 문제점인 최대값을 가져오기 위해서 동일 테이블을 2번 읽어야 하는 경우이다.
고객에 해당하는 현금영수증의 최대값을 가져와서 해당 현금영수증정보 엔터티에 다시 현금영수증일련번호를 공급해서 처리하고 있다.

 

개선한 SQL)

SELECT  /*+ ORDERED USE_NL(A B) */
        A.주문번호
       ,A.주문일시
       ,B.현금영수증일련번호
       ,현금영수증관련 속성
  FROM  주문 A
       ,현금영수증정보 B
 WHERE A.고객번호 = B.고객번호
   AND B.ROWID =        (SELECT    /*+ INDEX_DESC(B 인덱스01) */
                                      SUBSTR(MAX(LPAD(현금영수증일련번호,15,'0')||B.ROWID),16)
                                FROM  현금영수증정보 B
                                WHERE A.고객번호 = B.고객번호
                                  AND ROWNUM<=1)
   AND A.주문일시 BETWEEN SYSDATE-100 AND SYSDATE-99;

 

변경plan)

02.gif

 

 

 

PLAN을 보면 한번만 읽고 처리 하고 있음.
해당 방법은 이력의 최대값을 공급해서 처리하는 경우에 유용하게 사용할수 있는 방법입니다.

Tag

Leave Comments