우리 회사 데이터베이스를 티베로로 변경하기
특정 컬럼 기준 MAX 가져오기의 비효율적 구성 0 0 75,670

by 티베로 티베로전환 티베로성능개선 [2018.09.30]


소속 회사는 여러 금융 회사들로 부터 제출받은 여러 가지 공시/통계 보고서를 일련의 가공(입수>검증>승인) 절차를 거쳐 전자공시(http://dis.kofia.or.kr), 종합통계(http://freesis.kofia.or.kr) 등을 통해 서비스하고 있다.

이때 가공 과정에서 입수자료의 문제가 발견되면 제출회사에 요청하여 수정된 자료를 받아 다시 검증 절차를 거치게 되는데 이를 위해 다음과 같은 ‘제출이력’ 테이블을 구성하여 모든 자료들의 전체 이력(입수 HISTORY)을 관리하고 있으며 해당 이력 중 최종 제출된 보고서만(특정 컬럼 기준 MAX에 해당하는 ROWS) 서비스하게 된다

-- 제출이력 테이블 : PK 컬럼 : (제출 마감일, 상품코드, 제출회사코드, 회사코드, 보고서분류코드, 보고서버전, 보고서식별코드, SEQ)

즉 [제출 마감일, 상품코드, 제출회사코드, 회사코드, 보고서분류코드, 보고서버전, 보고서 식별코 드] 기준 MAX SEQ가 최종 제출 보고서이다

따라서 소속 회사의 매우 많은 SQL에서 위 제출 이력 테이블을 JOIN하여 특정 컬럼기준 MAX SEQ를 찾는 경우가 많은데, 대부분 다음 두 가지 형태로 구성되어 있다.

1) 자신의 테이블을 한 번 더 바라보며 MAX SEQ 찾기

SELECT *
FROM 제출이력테이블 A
WHERE A.기준일자 LIKE '201609%'
AND A.SEQ = (
 SELECT MAX(SEQ)
 FROM 제출 이력 테이블
 WHERE A.제출마감일 = 제출마감일
 AND A.상품코드 = 상품코드
 AND A.제출회사코드 = 제출회사코드
 AND A.회사코드 = 회사코드
 AND A.보고서분류코드 = 보고서분류코드
 AND A.보고서버전 = 보고서버전
 AND A.보고서식별코드 = 보고서식별코드
 )
 
 
2) 분석 함수 ROW_NUMBER를 사용
 
SELECT *
FROM (
 SELECT A.*
   , ROW_NUMBER() OVER 
     ( PARTITION BY 제출마감일, 상품코드, 제출회사코드
        , 회사코드, 보고서분류코드, 보고서버전, 보고서식별코드 
       ORDER BY 제출마감일, 상품코드, 제출회사코드, 회사코드
        , 보고서분류코드, 보고서버전, 보고서식별코드, SEQ DESC) AS RN
   FROM 제출이력테이블 A
  WHERE A.기준일자 LIKE '201609%'
 )
WHERE RN = 1; 

어느 구성이 더 효율적일까? 참고 4-11에서 보는 것처럼 티베로가 제공하는 분석함수인 ROW_NUMBER를 사용하는 것이 훨씬 유리하다.

ROW_NUMBER를 사용하지 않는 경우는 기준 컬럼들로 이루어진 PK_제출이력테이블 인덱스를 스캔하며 MAX(SEQ)를 찾아야 하지만 ROW_NUMBER를 사용할 경우 기준일자 조건에 해당하는 데이터를 IX_제출이력테이블 인덱스만 사용하여 해당하는 데이터를 ROWID를 통해 찾아 메모리에 올리고 분석 함수를 통해 빠르게 MAX(SEQ)를 찾아내므로 좋은 성능을 보인다.

다음의 예시는 CR GETS(CR BLOCK READ) 수치와 ELAPS.TIME(소요 시간)이 서로 큰 차이는 아니라고 판단할지도 모르나 추출 데이터가 커지고 한 개의 SQL 안에 위 형태가 반복 사용될 경우는 다음 예시보다 훨씬 큰 성능의 저하를 보인다.

그리고 더 큰 문제는 티베로 옵티마이저가 동일한 테이블의 반복적인 스캔을 피하고 조금 더 효율적인 방법으로 SQL을 수행하기 위해 쿼리를 변형하는 과정에서 부작용이 발생되어 외산 DBMS에 비해 성능이 크게 저하는 경우가 종종 발생하여 해당 SQL들은 ROW_NUMBER를 사용하는 방향으로 모두 수정하여 처리하였다.

본 장의 소개 과정에서 언급한 것처럼 위와 같은 부작용을 없애는 것은 향후 티베로가 노력해야 할 몫이지만 데이터베이스 제조사를 떠나 조금 더 효율적인 방법으로 SQL을 구성하는 것은 전환의 과정에서도 그리고 해당 SQL을 사용하는 어플리케이션의 성능 면에서도 좋은 일이기에 사전에 이와 같은 비효율은 제거하는 것은 매우 의미있는 일이라고 생각된다

  • [참고 4-11] ROW_NUMBER 사용 VS 미사용 성능 비교
  • MAX(SEQ)로 구성 시
  • ROW_NUMBER 사용 시

  • - 해당 강좌는 도서 " [우리 회사 데이터베이스를 티베로로 변경하기]"의 내용을 옮겼습니다.
  • - 해당 도서는 기간계 DBMS(DATABASE MANAGEMENT SYSTEM)를 티베로로 전환하는 실제 프로젝트를 수행한 실무자가 DBMS 전환 과정과 실제 적용 사례, 문제 해결 과정 등을 자세하게 설명하고 있습니다.

- 강좌 URL : http://www.gurubee.net/lecture/4131

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입