OS 환경 : Oracle Linux 9.6 (64bit)
DB 환경 : Oracle AI Database 23.26.3.0.0 ai
방법 : 오라클 26ai MULTI_APPEND, NO_MULTI_APPEND 힌트 테스트
오라클 26ai 버전부터 Direct Path Insert 수행 후 트랜잭션을 종료하지 않아도 동일한 테이블을 다시 조회하거나 DML, Direct Path Insert를 수행할 수 있음
기존 19c에서는 APPEND 힌트를 사용하여 Direct Path Insert를 수행한 경우 COMMIT 또는 ROLLBACK 전 해당 테이블을 다시 조회하거나 수정하면 ORA-12838 에러가 발생했음
26ai에서는 이러한 제약이 기본적으로 해제되어 있음
이 기능은 _online_direct_load 히든 파라미터로 제어됨
이 파라미터를 0으로 변경하면 기능이 이전 버전처럼 동작함(append insert 후 재 append insert 안됨)
참고 : 오라클 26ai 신기능 Direct Load(Direct Path Insert) 에 대한 제약 해제 ( https://positivemh.tistory.com/1127 )
_online_direct_load 히든 파라미터와 더불어 본문에서 테스트 하는 NO_MULTI_APPEND 힌트를 사용하면
26ai에서도 기존 버전과 동일하게 Direct Path Insert 이후 해당 테이블을 다시 조회하거나 수정할 때 ORA-12838 에러가 발생함
테스트
1. MULTI_APPEND 힌트 확인
2. 테스트 환경 확인
3. 샘플 테이블 생성
4. APPEND 기본 동작 테스트
5. APPEND + MULTI_APPEND 테스트
6. APPEND + NO_MULTI_APPEND 테스트
7. NOAPPEND와 비교
8. 결론
테스트
1. MULTI_APPEND 힌트 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
SQL>
set lines 200 pages 1000
col name for a30
col inverse for a30
col version for a15
select name, inverse, target_level, version
from v$sql_hint
where name in ('APPEND', 'NOAPPEND',
'MULTI_APPEND', 'NO_MULTI_APPEND')
order by name;
NAME INVERSE TARGET_LEVEL VERSION
------------------------------ ------------------------------ ------------ ---------------
APPEND NOAPPEND 1 8.1.0
MULTI_APPEND NO_MULTI_APPEND 1 23.1.0
NOAPPEND APPEND 1 8.1.0
NO_MULTI_APPEND MULTI_APPEND 1 23.1.0
|
23 버전(26ai)에 존재함
2. 테스트 환경 확인
db 버전 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
SQL>
set lines 200 pages 1000
select * from v$version;
BANNER
---------------------------------------------------------------------------------------------------------------------------------
BANNER_FULL
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BANNER_LEGACY CON_ID
--------------------------------------------------------------------------------------------------------------------------------- ----------
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production
Version 23.26.3.0.0
Oracle AI Database 26ai Enterprise Edition Release 23.26.3.0.0 - Production 0
|
23.26.3 버전임
COMPATIBLE 파라미터 확인
|
1
2
3
4
5
6
|
SQL> show parameter compatible
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
compatible string 23.6.0
noncdb_compatible boolean FALSE
|
23.6.0임
3. 샘플 테이블 생성
|
1
2
3
|
SQL>
drop table emp2 purge;
create table emp2 as select * from emp;
|
데이터 건수 확인
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
14
|
현재 14건의 데이터가 존재함
4. APPEND 기본 동작 테스트
실행계획 확인을 위해 statistics_level 파라미터 all로 변경
|
1
2
3
|
SQL> alter session set statistics_level = all;
Session altered.
|
26ai에서 별도의 MULTI_APPEND 힌트 없이 기존 APPEND 힌트만 사용
|
1
2
3
|
SQL> insert /*+ append */ into emp2 select * from emp2;
14 rows created.
|
14건이 추가되어 총 28건이 됨
COMMIT 하지 않은 상태에서 바로 실행계획 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST -rows -Projection +HINT_REPORT +outline');
Plan hash value: 1283500778
------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Writes | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 0 |00:00:00.01 | 13 | 1 | | | |
| 1 | LOAD AS SELECT | EMP2 | 1 | 0 |00:00:00.01 | 13 | 1 | 1043K| 1043K| 1043K (0)|
| 2 | OPTIMIZER STATISTICS GATHERING | | 1 | 14 |00:00:00.01 | 3 | 0 | 256K| 256K| |
| 3 | TABLE ACCESS FULL | EMP2 | 1 | 14 |00:00:00.01 | 2 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('23.1.0')
DB_VERSION('23.1.0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
OUTLINE_LEAF(@"INS$1")
LOAD_METHOD(@"INS$1" "EMP2"@"INS$1" HIGH_WATER_MARK)
LOAD_TYPE(@"INS$1" "EMP2"@"INS$1" SERIAL)
FULL(@"INS$1" "EMP2"@"INS$1")
FULL(@"SEL$1" "EMP2"@"SEL$1")
END_OUTLINE_DATA
*/
33 rows selected.
|
LOAD AS SELECT 실행계획이 나오고 outline data 부분에 LOAD_METHOD(HIGH_WATER_MARK)가 나온것을 보고 append 힌트가 제대로 동작했음을 알수 있음
COMMIT 하지 않고 EMP2 테이블 조회
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
28
|
정상적으로 28건이 조회됨
기존 19c에서는 이 시점에 ORA-12838 에러가 발생하지만
26ai에서는 정상적으로 조회됨
참고 : 오라클 26ai 신기능 Direct Load(Direct Path Insert) 에 대한 제약 해제 ( https://positivemh.tistory.com/1127 )
COMMIT 하지 않고 APPEND 재수행
|
1
2
3
|
SQL> insert /*+ append */ into emp2 select * from emp2;
28 rows created.
|
정상적으로 28건이 추가됨
다시 조회
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
56
|
총 56건이 정상적으로 조회됨
26ai에서는 APPEND 힌트만 사용한 경우 하나의 트랜잭션 내에서 Direct Path Insert 후 조회 및 Insert 재수행이 가능함
테스트 데이터 원복
|
1
2
3
|
SQL> rollback;
Rollback complete.
|
5. APPEND + MULTI_APPEND 사용
실행계획 확인을 위해 statistics_level 파라미터 all로 변경
|
1
2
3
|
SQL> alter session set statistics_level = all;
Session altered.
|
이번에는 APPEND 힌트와 MULTI_APPEND 힌트를 같이 사용해봄
|
1
2
3
|
SQL> insert /*+ append multi_append */ into emp2 select * from emp2;
14 rows created.
|
COMMIT 하지 않은 상태에서 바로 실행계획 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST -rows -Projection +HINT_REPORT +outline');
Plan hash value: 1283500778
------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Writes | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 0 |00:00:00.01 | 45 | 1 | | | |
| 1 | LOAD AS SELECT | EMP2 | 1 | 0 |00:00:00.01 | 45 | 1 | 1043K| 1043K| 1043K (0)|
| 2 | OPTIMIZER STATISTICS GATHERING | | 1 | 14 |00:00:00.01 | 8 | 0 | 256K| 256K| |
| 3 | TABLE ACCESS FULL | EMP2 | 1 | 14 |00:00:00.01 | 7 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('23.1.0')
DB_VERSION('23.1.0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
OUTLINE_LEAF(@"INS$1")
LOAD_METHOD(@"INS$1" "EMP2"@"INS$1" HIGH_WATER_MARK)
LOAD_TYPE(@"INS$1" "EMP2"@"INS$1" SERIAL)
FULL(@"INS$1" "EMP2"@"INS$1")
FULL(@"SEL$1" "EMP2"@"SEL$1")
END_OUTLINE_DATA
*/
33 rows selected.
|
동일하게 LOAD AS SELECT 실행계획이 나오고 outline data 부분에 LOAD_METHOD(HIGH_WATER_MARK)가 나온것을 보고 append 힌트가 제대로 동작했음을 알수 있음
LOAD_METHOD, LOAD_TYPE 힌트 부분이 append 힌트만 사용했을때와 동일함
COMMIT 하지 않고 EMP2 테이블 조회
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
28
|
정상적으로 28건이 조회됨
기존 19c에서는 이 시점에 ORA-12838 에러가 발생하지만
26ai에서는 정상적으로 조회됨
참고 : 오라클 26ai 신기능 Direct Load(Direct Path Insert) 에 대한 제약 해제 ( https://positivemh.tistory.com/1127 )
COMMIT 하지 않고 APPEND MULTI_APPEND 재수행
|
1
2
3
|
SQL> insert /*+ append multi_append */ into emp2 select * from emp2;
28 rows created.
|
정상적으로 28건이 추가됨
다시 조회
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
56
|
총 56건이 정상적으로 조회됨
26ai에서는 APPEND 힌트와 MULTI_APPEND 힌트를 사용한 경우 하나의 트랜잭션 내에서 Direct Path Insert 후 조회 및 Insert 재수행이 가능함
테스트 데이터 원복
|
1
2
3
|
SQL> rollback;
Rollback complete.
|
6. APPEND + NO_MULTI_APPEND 테스트
실행계획 확인을 위해 statistics_level 파라미터 all로 변경
|
1
2
3
|
SQL> alter session set statistics_level = all;
Session altered.
|
이번에는 APPEND 힌트와 NO_MULTI_APPEND 힌트를 같이 사용해봄
|
1
2
3
|
SQL> insert /*+ append no_multi_append */ into emp2 select * from emp2;
14 rows created.
|
COMMIT 하지 않은 상태에서 바로 실행계획 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST -rows -Projection +HINT_REPORT +outline');
Plan hash value: 1283500778
------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers | Writes | OMem | 1Mem | Used-Mem |
------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 0 |00:00:00.01 | 13 | 1 | | | |
| 1 | LOAD AS SELECT | EMP2 | 1 | 0 |00:00:00.01 | 13 | 1 | 1043K| 1043K| 1043K (0)|
| 2 | OPTIMIZER STATISTICS GATHERING | | 1 | 14 |00:00:00.01 | 8 | 0 | 256K| 256K| |
| 3 | TABLE ACCESS FULL | EMP2 | 1 | 14 |00:00:00.01 | 7 | 0 | | | |
------------------------------------------------------------------------------------------------------------------------------
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('23.1.0')
DB_VERSION('23.1.0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
OUTLINE_LEAF(@"INS$1")
LOAD_METHOD(@"INS$1" "EMP2"@"INS$1" HIGH_WATER_MARK)
LOAD_TYPE(@"INS$1" "EMP2"@"INS$1" SERIAL)
FULL(@"INS$1" "EMP2"@"INS$1")
FULL(@"SEL$1" "EMP2"@"SEL$1")
END_OUTLINE_DATA
*/
33 rows selected.
|
동일하게 LOAD AS SELECT 실행계획이 나오고 outline data 부분에 LOAD_METHOD(HIGH_WATER_MARK)가 나온것을 보고 append 힌트가 제대로 동작했음을 알수 있음
LOAD_METHOD, LOAD_TYPE 힌트 부분이 append 힌트만 사용했을때와 동일함
COMMIT 하지 않고 EMP2 테이블 조회
|
1
2
3
4
5
6
|
SQL> select count(*) from emp2;
select count(*) from emp2
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
Help: https://docs.oracle.com/error-help/db/ora-12838/
|
19c 환경처럼 에러가 발생함
COMMIT 하지 않고 APPEND NO_MULTI_APPEND 재수행
|
1
2
3
4
5
6
|
SQL> insert /*+ append no_multi_append */ into emp2 select * from emp2;
insert /*+ append no_multi_append */ into emp2 select * from emp2
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
Help: https://docs.oracle.com/error-help/db/ora-12838/
|
19c 환경처럼 에러가 발생함
26ai에서는 APPEND 힌트와 NO_MULTI_APPEND 힌트를 사용한 경우 하나의 트랜잭션 내에서 Direct Path Insert 후 조회 및 Insert 재수행이 불가능함
19c 환경처럼 에러가 발생함
테스트 데이터 원복
|
1
2
3
|
SQL> rollback;
Rollback complete.
|
7. NOAPPEND와 비교
NO_MULTI_APPEND와 NOAPPEND의 차이를 확인해봄
먼저 NOAPPEND 힌트만 사용하여 insert 수행
|
1
2
3
|
SQL> insert /*+ noappend */ into emp2 select * from emp2;
14 rows created.
|
COMMIT 하지 않은 상태에서 바로 실행계획 확인
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
SQL> SELECT * FROM DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST -rows -Projection +HINT_REPORT +outline');
Plan hash value: 2941272003
----------------------------------------------------------------------------------
| Id | Operation | Name | Starts | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 0 |00:00:00.01 | 37 |
| 1 | LOAD TABLE CONVENTIONAL | EMP2 | 1 | 0 |00:00:00.01 | 37 |
| 2 | TABLE ACCESS FULL | EMP2 | 1 | 14 |00:00:00.01 | 7 |
----------------------------------------------------------------------------------
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('23.1.0')
DB_VERSION('23.1.0')
ALL_ROWS
OUTLINE_LEAF(@"SEL$1")
OUTLINE_LEAF(@"INS$1")
LOAD_METHOD(@"INS$1" "EMP2"@"INS$1" CONVENTIONAL)
LOAD_TYPE(@"INS$1" "EMP2"@"INS$1" SERIAL)
FULL(@"INS$1" "EMP2"@"INS$1")
FULL(@"SEL$1" "EMP2"@"SEL$1")
END_OUTLINE_DATA
*/
32 rows selected.
|
실행계획에서 LOAD TABLE CONVENTIONAL이 보임
direct path insert가 아닌 conventional insert로 동작했다는 뜻임
이 경우에는 COMMIT 하지 않고 조회시 잘 조회됨
|
1
2
3
4
5
|
SQL> select count(*) from emp2;
COUNT(*)
----------
28
|
다시 INSERT도 당연히 잘됨
|
1
2
3
|
SQL> insert into emp2 select * from emp2;
28 rows created.
|
테스트 데이터 원복
|
1
2
3
|
SQL> rollback;
Rollback complete.
|
결론 :
오라클 26ai에서는 APPEND 힌트를 사용하여 Direct Path Insert를 수행한 후에도
트랜잭션을 종료하지 않고 동일한 테이블을 조회하거나 추가 Direct Path Insert를 수행할 수 있음
APPEND만 사용한 경우와 APPEND + MULTI_APPEND를 명시한 경우 동일하게 동작하는 것을 확인할 수 있음
반면 APPEND + NO_MULTI_APPEND 힌트를 사용하면 Direct Path Insert 자체는 그대로 수행되지만
Direct Path Insert 이후 동일 테이블에 접근할 때 기존 19c와 동일하게 ORA-12838 에러가 발생함
NO_MULTI_APPEND는 APPEND를 Conventional Insert로 변경하는 힌트가 아니라
26ai에서 해제된 Direct Path Insert의 트랜잭션 제약을 다시 적용하는 용도로 보임
_online_direct_load 히든 파라미터의 힌트 버전? 같은 느낌으로 보면 될것 같음
요약 :
NOAPPEND
- APPEND와 반대되는 힌트
- Direct Path Insert를 사용하지 않음
- Conventional Insert로 수행
- 동일 트랜잭션에서 조회 가능
NO_MULTI_APPEND
- APPEND 힌트와 함께 사용 가능
- Direct Path Insert는 그대로 사용
- LOAD AS SELECT로 수행
- Direct Path Insert 이후 SELECT 또는 추가 DML 수행시 ORA-12838 발생
MULTI_APPEND
- APPEND 힌트와 함께 사용 가능
- Direct Path Insert는 그대로 사용
- LOAD AS SELECT로 수행
- Direct Path Insert 이후 SELECT 또는 추가 DML 수행시 에러 미발생(26ai 기본값)
참조 :
오라클 26ai 신기능 Direct Load(Direct Path Insert) 에 대한 제약 해제 ( https://positivemh.tistory.com/1127 )
오라클 26ai 신기능 load_method, load_type 힌트 ( https://positivemh.tistory.com/1128 )
오라클 26ai 신기능 Parallel DML 에 대한 트랜잭션 제한 해제 ( https://positivemh.tistory.com/1176 )
https://oracle-randolf.blogspot.com/2023/08/oracle-23c-free-unrestricted-direct.html
https://tuna.tistory.com/102
'ORACLE > Admin' 카테고리의 다른 글
| 오라클 19c tar 명령을 이용해 db 엔진 복제시 유의사항 (0) | 2026.09.28 |
|---|---|
| 오라클 19c 타임존 업그레이드 가이드 (0) | 2026.09.04 |
| 오라클 19c ACFS 크기 변경 방법 (0) | 2026.09.01 |
| 오라클 19c 싱글 DB에 OCW 패치를 해야할까? (0) | 2026.08.26 |
| 오라클 19c oraInventory 비정상 시 runInstaller attachHome 재등록 방법 (0) | 2026.08.17 |
