본문 바로가기

Paul Work/Sql

/*+ APPEND */ 힌트의 진실과 거짓

 APPEND 힌트가 최고인가요?

 대량의 데이터를  INSERT 시킬때 많이 사용하는 구문 중에 하나가

INSERT INTO big_table
SELECT * FROM all_objects;

 라는건 많이 아실 겁니다.

(물론 테이블 drop후 create table big_table as select * ~~~~이 더 빠르긴 함. 상황이 다르지만)

 그럼 저 구문을 더 빠르게 할려면 어떻게 하냐의 질문에는
아마 많은 분들이 append 힌트를 쓰라고 하실겁니다.. 저두 그렇구요.

INSERT /*+ APPEND */ INTO big_table
SELECT * FROM all_objects;

 그럼 APPEND 힌트를 쓰면 리두 로그가 생성되지 않아 빠르게 수행된다고 생각하시겠죠..

APPEND 힌트와 같이 직접 경로 삽입은 아래 두가지 경우에만 로그를 생성하지 않는다는군요.
1) NOARCHIVELOG 모드 데이터베이스가 사용되고 있는 경우
2) NOLOGGING으로 표시된 테이블을 대상으로 작업하고 있는 경우

안타깝게도... 저희는 개발서버를 제외하고는 DB복구를 위해 ARCHIVELOG로 되어있구요.
NOLOGGING로 된 테이블도 하나도 없습니다. 그리고 대부분이 그러지 않을까 싶은데요.
그러니 실제로 프로그램 상에서 삽입된 /*+ APPEND */ 는 거의 있으나마나 했던게 아닐까
싶은 생각이 들더군요.

위의 두조건을 빼고서라도 만약 해당 테이블에 인덱스라도 걸려있다면
인덱스는 로그를 남기므로 로그의 용량이 엄청 증가를 하게 됩니다.

이제 우리는 APPEND 힌트에 대해 의문을 가져야 할 거 같습니다. 분명 유용한 힌트지만..
프로그램에서 사용할때는.. 위의 상황을 잘 유념해서 사용해야 할 듯 합니다.

그렇다고 모든 테이블에 NOLOGGING으로 설정하여, 디스크가 망가졌을때 복원을 못하는 사태를
만들지는 마세요.

 * 테이터 웨어하우스 또는 데이터 마트에 대량 데이터를 적재하는 경우

1. 인덱스를 UNUSABLE 상태로 설정한다.(삭제하지 않고 잠시동안 사용할 수 없는 상태로 전환한다)
2. 대량 적재시 상태가 UNUSUABLE인 인덱스를 지나치도록 세션을 설정한다.
3. 인덱스를 다시 활성화한다.

선행 alter table big_table nologging 후 데이터 적재후 다시 변경
1. alter index big_table_idx unusable;
2. alter session set skip_unusable_indexes=true;
3. insert /*+ append */ into big_table select * from all_objects;
4. alter index big_table_idx rebuild nologging;

(drop index 명령이 정상적으로 실행된 후 여러가지 이유로 create index 명령이 실패한 사례를 수없이 보아왔다는 저자... 물론 인덱스가 유실되었음을 아무도 알아채지 못했으며 성능이 현저히 낮아졌다.)