권순용의 DB 이야기
생각의 전환이 데이터베이스를 최적화시킨다. 3부. 1 0 5,536

by axiom DIRECT LOAD APPEND DML 성능저하 DML 성능최적화 HWM NOLOGGING DB최적화 [2013.08.07]


DML에 대한 성능 저하는 누구나 경험하는 현상일 것이다. DML에 대한 성능 저하를 해결하기 위해서는 우리가 생각하고 있는 많 은 것에 대한 생각의 전환이 필요하다.

지난 강의에는 INSERT 및 UPDATE의 성능 저하를 확인해 보았다. 이번 강의에는 DELETE에 대한 성능 저하를 확인해 보자. 또한 INSERT, UPDATE,DELETE의 성능을 향상시키는 실질적인 방법을 확인해 보자.

DELETE 작업에 대한 성능 저하를 확인하자

DELETE 작업은 어떠한가? DELETE는 저장되어 있는 데이터를 삭제하는 기능을 수행하게 된다. 이와 같은 DELETE는 아래와 같은 항목들에 의해 성능이 저하된다.

  • - 로그 기록
  • - 인덱스의 개수
  • - 롤백을 위한 로그 기록
  • - 디스크 I/O

다른 항목은 INSERT 또는 UPDATE와 동일하다. 차이라면 로그 기록 및 롤백을 위한 로그 기록 시 삭제되는 데이터의 이전 데이터와 이후 데이터를 모두 기록해야 한다는 것이다.

물론 롤백을 위한 로그 기록 시에는 이전 데이터의 값과 위치 정보만을 가지게 된다. 결국, 이와 같은 이유로 동일한 양의 데이터를 DELETE하는 경우 INSERT에 비해 더 많은 디스크 I/O가 발생 하게 되므로 성능은 저하된다.

그럼 다양한 성능 저하의 요소를 가지는 DML 작업에서 대용 량의 데이터에 대해 어떤 방식으로 작업을 수행해야만 성능을 보 장 받을 수 있을까?

INSERT의 성능 저하 요소를 감소시키자

일반적으로 DELETE 또는 UPDATE의 경우에는 INDEX의 개수만을 최적화해 성능을 향상시킬 수 있다. 하지만 INSERT의 경우에는 위와 같은 성능 저하의 요소 가운데 다음과 같은 요소 에 대해 획기적으로 감소시킬 수 있게 된다.

  • - 로그 기록
  • - HWM BUMP UP
  • - 롤백을 위한 로그 기록

위의 성능 저하 요소는 우리가 조금만 깊이 있게 고려한다면 최소화시킬 수 있으며 이 항목을 최소화시킨다면 디스크 I/O는 자동으로 감소하게 된다. 그렇다면 어떻게 이런 성능 저하 요소 를 감소시킬 수 있을까?

첫 번째로 HWM BUMP UP과 롤백을 위한 로그 기록을 감 소시키는 방법을 확인해 보자. HWM BUMP UP을 제거하기 위 해서는 HWM을 이동시키지 않고 데이터를 HWM 뒤에 존재하 는 블록에 저장하면 될 것이다.

이와 같다면 롤백 또한 이전 데이 터의 정보를 하나 하나 기록하는 것이 아니라 HWM의 위치 정 보 하나만을 기록한다면 롤백 수행 시 HWM 위치 뒤에 존재하 는 모든 블록을 제거하는 경우 롤백을 수행한 것과 동일한 현상 이 발생할 것이다.

결국, HWM을 고정시키고 데이터를 HWM 뒤에 존재하는 블 록에 저장시킨다면 HWM BUMP UP과 롤백을 위한 로그 기록 에 의해 발생하는 성능 저하는 해결될 수 있을 것이다.

이와 같이 INSERT를 수행하는 방법이 바로 직접 로딩(DIRECT LOADING) 방식이다. 직접 로딩 방식을 사용한다면 HWM 뒤 의 블록에 데이터를 저장하게 되므로 두 가지 문제는 모두 해결 될 수 있다.

그렇다면 직접 로딩은 어떻게 사용하는 것인가?

INSERT /*+ APPEND */ …… SELECT ……

위와 같이 SELECT를 수행해 해당 데이터를 테이블에 INSERT하는 경우에 APPEND 힌트를 사용해 직접 로딩을 수 행하게 된다.

두 번째로 로그 기록을 확인해 보자. 우리가 테이블에 데이터 를 저장하는 경우 일반적으로는 LOGGING 상태이므로 앞서 언 급한 모든 로그를 기록하게 된다.

하지만 직접 로딩(DIRECT LOADING) 기법을 사용하게 된다면 HWM 뒤에 존재하는 블 록에 데이터를 저장하게 되므로 별도의 로그를 기록하지 않아도 복구 시 HWM 뒤의 블록에 존재하는 데이터를 제거하면 될 것 이다.

이와 같은 이유에서 직접 로딩 방식의 경우에는 로그를 기 록하지 않는 NOLOGGING 방식으로 데이터를 저장할 수 있게 된다.

결국. 이와 같이 NOLOGGING 상태에서 직접 로딩을 수행한 다면 앞서 언급한 세 가지의 성능 저하 요소를 대부분 제거할 수 있으며 이로 인해 디스크 I/O는 감소하게 된다.

상황에 따라 다 르지만 대용량의 데이터에 대해 NOLOGGING 상태의 직접 로 딩은 일반 INSERT에 비해 10배 이상 성능을 향상시킬 수 있다.

DELETE와 UPDATE의 성능을 최적화하자

대용량의 데이터에 대해 DELETE 또는 UPDATE를 수행한 다면 엄청난 성능 저하가 발생할 수 있다.

DELETE 또는 UPDATE는 INSERT에 비해 더 많은 자원을 사용하게 되며 직 접 로딩 또는 NOLOGGING 상태와 같은 방법이 존재하지 않게 된다.

많은 데이터에 대해서는 과거나 지금이나 성능 저하를 감수 할 수밖에 없을 것이다. 하지만 이와 같은 대용량의 DELETE 또 는 UPDATE에 대해서도 성능을 최적화시키는 방법은 존재한다.

우리는 데이터를 변경하기 위해서는 항상 UPDATE를 사용해 야 하고 데이터를 삭제하기 위해서는 항상 DELETE를 수행해 야 한다.

일반적으로 생각한다면 이는 당연한 사실일 것이다. 하 지만 이와 같은 고정 관념으로는 대용량의 데이터에서 더 이상의 성능 향상을 기대할 수 없을 것이다.

대용량의 데이터에 대해 UPDATE 또는 DELETE를 수행하는 경우 최적의 성능을 보장 받기 위해서는 기존의 사고방식에서 벗어나야 할 것이다.

대용량의 데이터 환경에서 데이터를 변경하는 경우 UPDATE 로 작업을 수행하지 말고, 데이터 삭제의 경우에는 DELETE로 작업을 수행하지 말아야 한다.

UPDATE는 INSERT로 변경하 고 DELETE 또한 INSERT로 변경하는 순간 최적의 성능을 기 대할 수 있을 것이다.

UPDATE를 INSERT로, DELETE를 INSERT로 수행하는 것이야말로 우리의 기존 고정 관념을 파괴 하는 행위일 것이다. 이제는 이와 같은 기존의 고정 관념을 파괴 해 성능을 최적화해야 할 것이다.

그렇다면 어떤 이유에서 UPDATE 또는 DELETE 대신 INSERT를 사용해야 하는가?

이유는 간단하다. INSERT는 UPDATE나 DELETE와는 달리 직접 로딩과 NOLOGGING이 가능하기 때문이다. 이와 같은 성 능 향상의 요소는 우리에게 엄청난 혜택을 가져다 준다.

그렇다면 어떻게 UPDATE를 INSERT로 변경하고 DELETE 를 INSERT로 변경할 수 있겠는가?

물론, 데이터 삭제에 INSERT를 사용해야 하기 때문에 작업 절차는 복잡해질 수 있 다.

예를 들어, TEST 테이블의 크기가 100GB이며 그 중 50GB 에 해당하는 데이터를 삭제해야 한다고 가정하자. 그렇다면 DELETE를 수행하는 순간 우리는 꽤 오랜 시간을 기다려야 해 당 작업을 종료할 수 있을 것이다.

DELETE를 INSERT로 변경 한다면 어떻게 되겠는가? 우선, TEST 테이블과 동일 구조의 TEST_IMSI 테이블을 생성한 후 TEST 테이블로부터 데이터가 삭제된 후 남게 되는 데이터만을 조회해 TEST_IMSI 테이블에 INSERT를 수행한다.

해당 작업에서는 TEST_IMSI 테이블을 NOLOGGING 상태로 변경한 후 해당 테이블에 직접 로딩을 수 행해야 할 것이다.

고성능의 디스크를 사용하는 시스템이라면 1GB에 1분 정도의 INSERT 시간이 소요된다. 50GB의 데이터 를 INSERT하면 되므로 최적화된다면 50분 정도의 시간이 소요 될 것이다.

이 얼마나 빠른 속도인가? 물론, 경우에 따라 병렬 프 로세싱을 이용해야 할 수도 있다. 이와 같이 작업을 수행했다고 모든 것이 종료되는 것은 아니다.

TEST 테이블을 TEST_BACKUP으로 이름을 변경하고 TEST_IMSI 테이블을 TEST 테이블로 이름을 변경해야 할 것이다. 물론, 인덱스가 필요하다 면 인덱스도 생성해야 한다.

이와 같이 작업 절차는 복잡해지지만 DELETE를 수행하는 것보다는 10배 이상 성능이 향상될 것이다. UPDATE의 경우도 이와 다르지 않다.

UPDATE 후의 데이터를 임시 테이블에 INSERT하고 해당 테이블의 이름을 변경한다면 기존 테이블에 는 UPDATE 후의 데이터가 저장되므로 INSERT를 이용해 UPDATE를 대신할 수 있게 된다.

이와 같은 방식으로 기존의 방식에서 벗어날 수 있다면 우리는 최적의 성능을 기대할 수 있 을 것이다.

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

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

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

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