복잡한 선택적 조건절을 사용하는 경우, 옵티마이저가 최적 실행계획을 수립하기 어려운데, 쿼리 수정 또는 USE_CONCAT 힌트 사용을 통해 OR EXPANSION을 유도하거나, UNION ALL 구문으로 입력 케이스별로 실행계획을 강제적으로 분리시키는 방법을 사용하여 성능을 최적화 한다.
개선 전 - 트레이스 결과
- (문제 상황) 외환기본_IX08 인덱스 액세스에 대부분의 시간이 소요됨
- IX08 인덱스가 거래일자와 과목코드 순으로 구성되어 있어서, 거래일자 범위 조건은 인덱스 access 조건이 되었지만, 과목코드 조건을 인덱스 filter 조건이 됨 (참고로, 과목코드 값이 ‘EX’인 것은 전체 로우의 약 5%임)
개선 전 - SQL문
- (문제 원인) 고객번호 및 관리점번호 입력값이 필수가 아니어서, 해당 값 입력 여부에 따라 최적 실행계획이 달라질 수 있는데, 앞의 실행계획을 보면, 고객번호(:B3) 입력 여부 따라 실행계획이 분리되었음 (CONCATENATION/FILTER 오퍼레이션 등장)
- INDEX 힌트를 사용하여 항상 IX08 인덱스가 사용되도록 했는데, 이 INDEX 힌트를 제거하더라도 최적 실행계획이 수립되지 않았음
개선 방안
- (개선 방안) 고객번호와 관리점번호 입력 여부에 따른 3가지 경우 각각을 구분하여 처리할 수 있도록 UNION ALL 사용
- 이때, 배타적인 3개 집합은 반드시 상호 배제되고 전체를 포괄해야 함 (MECE, Mutually Exclusive, Collectively Exhaustive)
개선 후
- (개선 결과) 3가지 경우 각각에 최적인 실행계획이 수립됨(각각 IX01, IX04, IX08 인덱스를 사용)
- (개선 결과) 본 사례는 고객번호가 입력된 경우로서 IX01 인덱스가 사용되었고, 개선 전에 비해 액세스량/소요시간이 현저히 감소함
댓글
댓글 쓰기