시계열성으로 쌓여진 (대용량) 거래 내역을 특정 고객번호로 조회하면, 액세스할 블록이 거의 로우당 1개인 경우가 일반적인데, 이때 고객번호별로 데이터를 모아두는 정렬재구성을 하면, 액세스해야 할 블록이 크게 감소한다.
참고로, 온라인 업무나 업무 배치 처리 과정에서 자연스럽게 데이터가 흩어진게 아니고, 차세대/고도화 사업 데이터이행 과정에서 데이터가 크게 흩어지는 경우도 빈번하다.
개선 전
- (문제 상황) 평이한 실행계획이나 넓은 데이터 범위를 액세스하면서 10초 가량 소요됨(특히 계좌가 많은 기업고객인 경우)
- (문제 원인) 16천 여건의 결과 모두를 리턴해야 하므로 절대적으로 많은 시간이 소요될 수 밖에 없고, 특히 클러스터링 팩터가 좋지 못해 읽은 로우수에 비해 읽은 블록도 많은 편임 - 인덱스 스캔 결과가 16899건 인데, 테이블 (12182-281) 블록을 읽었음
- 참고로, 조건절 정보(Predicate Information)를 볼때, IX04 인덱스는 고객번호+...+여신활동구분코드로 구성되어 있음을 추정할 수 있음
문제 원인 분석
- 기업고객의 계좌가 한꺼번에 개설되지 않고 시차를 두고 개설되었다면 해당 고객의 계좌 정보는 각기 다른 데이터 블록에 저장됨
- 참고로 하나의 데이터 블록은 (보통) 8K byte 크기이며, 대개 100건 이상의 로우가 저장될 수 있음
- 참고로, 차세대 또는 통합 프로젝트의 데이터이행 과정을 통해서도 데이터가 크게 흩어질 수 있음
- 계좌 데이터가 저장된 모든 데이터 블록을 액세스 해야 하는데, 여신계약기본과 같은 대형 테이블의 데이터 블록이 DB 캐시에 있을 확률은 (보통) 10% 내외이므로 거의 계좌 건수 만큼 물리 읽기를 해야 함
- 이 DB의 경우 물리 읽기 1회 당 1ms~5ms 정도 소요되므로, 10000건의 계좌를 읽는데, (DB 서버 구간에서만) 10~50초가 소요될 수 있음
개선 방안
- 계좌가 많은 고객번호로 여신계약기본을 고객번호로 조회하는 경우에 겪게되는 성능 이슈이므로 테이블을 고객번호로 정렬재구성하여 데이터 분산도를 개선함
- 여신계약기본의 경우, 계좌번호로 파티션되어 있고, 인덱스가 모두 ‘Local’이어서 파티션 단위 작업이 가능함
- DBA가 작성한 스크립트로 정렬 작업 가능하나, 업무 중지 시간이 확보되어야 한다는 어려움이 있음
- LiveReorg 같은 온라인 리오그 솔루션을 이용하면, 업무 중지 없이 작업 가능함(단, 그럼에도 거래가 빈번한 시간대는 피해서 작업하는 것을 권고)
- 위의 예시로 보면, 종전 5개 블록을 읽었던 쿼리문이, 정렬 후 1개 블록만 읽으면 됨
- 개선전 테이블에서 1만여 블록의 물리 읽기가 발생했는데, 정렬재구성 수행하면 약 80%이상 감소할 것으로 예상됨
- 물리 읽기가 80% 감소된다면 종전 소요 시간이 10초인 쿼리문이 2초로 단축되는 효과가 있음을 의미함
잘봤습니다. 결과건수보다 read한 블럭이 현저하게 적어야하는게 핵심이군요.
답글삭제그렇습니다. 다만, Reads 수와 Buffers 수를 함께 봐야, 좀 더 정확한 판단을 할 수 있을 거 같습니다.
삭제