INSERT APPEND, APPEND_VALUES에 관련된 내용 입니다.

 

출처는 아래와 같습니다.

 

 

출처: http://ukja.tistory.com/317 [오라클 성능 문제에 대한 통찰 - 조동욱]

출처: http://ukja.tistory.com/317 [오라클 성능 문제에 대한 통찰 - 조동욱]

출처: http://ukja.tistory.com/317 [오라클 성능 문제에 대한 통찰 - 조동욱]

출처: http://ukja.tistory.com/317 [오라클 성능 문제에 대한 통찰 - 조동욱]

 

 

 

한건의 로우(Row)를 Insert하는데 APPEND 힌트를 이용한 Direct Path Mode가 필요한지는 잘 모르겠습니다. 어쨌든 오라클은 11g부터 이러한 모드를 지원하기로 했습니다. 즉 INSERT ... VALUES ... 구문에서도 APPEND 힌트가 동작하도록 수정되었습니다. 좀 더 상세하게 정리를 해보면

  • Oracle 10g까지는 INSERT ... VALUES ... 구문에 APPEND 힌트를 부여해도 무시됩니다. 즉, APPEND 힌트는 INSERT ... SELECT 구문에서만 동작합니다.
  • APPEND 힌트로 인해 Direct Path Mode로 동작하면 로우를 Insert할 때 현재 세그먼트의 Free Block을 무시하고(동시에 Buffer Cache를 경유하지 않고) 세그먼트의 High Water Mark 뒤에 Append 시켜버립니다. 따라서 대량의 데이터를 추가할 때 속도는 빠르지만 데이터 파일에 그만큼 불필요한 빈공간이 남아있을 수는 있습니다. (하지만 이 빈공간도 언젠가는 사용될 것입니다)
  • Oracle 11gR1에서는 INSERT ... VALUES ... 구문에서도 APPEND 힌트가 동작합니다. 히든 파라미터 _direct_path_insert_features에 의해 제어됩니다.
  • Oracle 11gR2에서는 INSERT ... VALUES ... 구문에서 APPEND 힌트를 부여해도 무시됩니다(응?). 대신 APPEND_VALUES 라는 힌트가 추가되었습니다. 즉 APPEND_VALUES 힌트를 사용하면 INSERT ... VALUES ... 구문에서도 Direct Path Mode로 Insert가 이루어집니다.
간단한 테스트 결과입니다.
create table t1(c1 number);

insert into t1 values(1);
commit;
insert into t1 values(2);
commit;

-- (2건의 로우를 Insert했고 Conventional Path Mode이므로 두 개의 로우가 같은 Block에 있을 것입니다)
select
	dbms_rowid.rowid_relative_fno(rowid) as file#,
	dbms_rowid.rowid_block_number(rowid) as block#
from t1;

-- 10.2.0.1
     FILE#     BLOCK#
---------- ----------
         4        853
         4        853

-- 11.1.0.6
     FILE#     BLOCK#
---------- ----------
         4        758
         4        758

-- (APPEND 힌트를 부여한 INSERT ... VALUES 구문입니다)
insert /*+ append */ into t1 values(3);
commit;

-- 10.2.0.1에서는 APPEND 힌트가 무시되므로 역시 같은 Block에 Insert 됩니다.
     FILE#     BLOCK#
---------- ----------
         4        853
         4        853
         4        853

-- 하지만 11.1.0.6에서는 APPEND 힌트가 동작했고, 그 결과 High Water Mark의 끝 이후로 Insert 되어 버립니다.
     FILE#     BLOCK#
---------- ----------
         4        758
         4        758
         4        769

-- 11.2.0.1에서는 APPEND_VALUES 힌트가 그 역할을 대신합니다.
iinsert /*+ append_values */ into t1 values(3);
commit;

     FILE#     BLOCK#
---------- ----------
         4        526
         4        526
         4        528
왜 오라클 개발자들이 갑자기 INSERT ... VALUES ... 구문에서도 APPEND 힌트가 동작하도록 바꾼 것일까요? 아무리 생각해도 모르겠습니다.

아마 이전에 일하던 개발자가 그만두고 가면서 인수인계가 잘 안되었나봅니다. 이 모든 것은 사람이 하는 것이기에... :)



 

Posted by 나른한스누피