메뉴 건너뛰기

Korea Oracle User Group

Admin

default 값을 포함한 컬럼 추가시 오라클 버전별 개선 사항

1. 11g 이전 버전의 경우

컬럼 추가 후 default 값으로 추가된 컬럼이 내부적으로 update가 발생한다.

만약 update 트리거가 걸려 있다면 트리거도 발동된다.

 

2. 11g 이후 버전의 경우

nullable 인지 아닌지 여부에 내부 작업 동작이 바뀐다.

not null 제약도 포함할 경우 내부적인 update 없이 메타데이터로 default 값이 내부에 저장이 된다.

그리고 데이터 조회시에 메타정보에서 default 값을 가져오는 구조이다.

nullable 인 경우 이전과 같은 방식으로 동작하게 된다.

 

아래는 이와 관련한 내용의 테스트 내용이다.

 

-- 테스트 데이터 생성

 

16:53:42 db_mon> exec dbms_application_info.set_module('db_mon','db_mon');
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:00:00.00
16:55:24 db_mon> CREATE TABLE col_add_test
16:55:30   2  AS
16:55:30   3  SELECT * FROM dba_objects 
16:55:30   4  WHERE 1=0;
 
Table created.
 
Elapsed: 00:00:00.03
16:55:30 db_mon> BEGIN
16:55:35   2      FOR C IN 1 .. 20
16:55:35   3      LOOP
16:55:35   4          INSERT INTO col_add_test
16:55:35   5              SELECT * FROM DBA_OBJECTS;
16:55:35   6  
16:55:35   7          COMMIT;
16:55:35   8      END LOOP;
16:55:35   9  END;
16:55:35  10  /
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:01:01.52

 

nullable 이면서 default 값을 가지는 컬럼을 추가해 본다

 

16:56:37 db_mon> alter table col_add_test add (col1 varchar2(100default 'add column test');
 
Table altered.
 
Elapsed: 00:02:07.73
16:58:55 db_mon> 

 

시간이 2분 7초 소요된 것을 확인할 수 있다.

 

아래는 위 작업세션에 대해 세션 모니터링 한 결과이다.

 

16:58:45 db_mon> @kwan_mon db_mon
#### Session info ####
 
       SID    SERIAL# USERNAME   MODULE               TADDR
---------- ---------- ---------- -------------------- ----------------
      1038      12363 DB_MON     db_mon               C0000003E4F865E0
 
1 row selected.
 
#### Transaction info ####
 
       SID    SERIAL# USERNAME   START_TIME           UNDO        USED_UREC  USED_UBLK     LOG_IO     PHY_IO     CR_GET  CR_CHANGE ADDR
---------- ---------- ---------- -------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------------
      1038      12363 DB_MON     01/16/23 16:56:47    549.57M       6739888      70345   24165792      24534    1389817    1055264 C0000003E4F865E0
 
1 rows selected.
 
16:58:54 db_mon> 

 

모니터링 결과를 보면 트랜잭션이 발생하며 undo가 쌓이는 것을 확인할 수 있다.

즉, 내부적으로 update 트랜잭션이 발생한다는 것이다.

 

그럼, 이제 not null 이면서 default 값을 가지는 컬럼을 추가해 본다

 

16:58:55 db_mon> alter table col_add_test add (col2 varchar2(100default 'add column test' not null);
 
Table altered.
 
Elapsed: 00:00:00.05
17:16:08 db_mon>

 

수행시간이 1초도 걸리지 않았다.

같은 컬럼 추가지만 not null 제약 조건을 걸면 위와 같이 내부적으로 update가 발생하지 않는다.

모니터링 해 보면 트랜잭션도 발생하지 않는 것을 확인할 수 있다.

 

이와 같이 11g 버전부터는 default 값을 갖는 컬럼을 추가할 때 not null 제약 조건을 걸 경우 예전과 다르게 내부적으로 update를 수행하지 않는다.

작업 시간은 줄고 내부적으로 발생하는 update로 인한 서비스 문제도 발생하지 않게 되었다.

 

2. 12.1c 이후 버전의 경우

11g 버전과 다르게 nullable 인 컬럼에 default를 설정하고 추가해도 빨리 끝난다.

컬럼의 default 값이 not null, nullable 두 경우 모두 메타데이터로 저장된다.

 

아래는 이와 관련한 테스트 내용이다.

 

13:22:04 DB_MON> CREATE TABLE col_add_test
  2  AS
  3  SELECT * FROM dba_objects 
  4  WHERE 1=0;
 
Table created.
 
Elapsed: 00:00:00.186
13:22:19 DB_MON> BEGIN
  2      FOR C IN 1 .. 20
  3      LOOP
  4          INSERT INTO col_add_test
  5              SELECT * FROM DBA_OBJECTS;
  6  
  7          COMMIT;
  8      END LOOP;
  9  END;
 10  /
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:00:12.216
13:24:06 DB_MON> alter table col_add_test add (col1 varchar2(100default 'add column test');
 
Table altered.
 
Elapsed: 00:00:00.082
13:25:19 DB_MON> alter table col_add_test add (col2 varchar2(100default 'add column test' not null);
 
Table altered.
 
Elapsed: 00:00:00.040
13:25:32 DB_MON> 

 

not null, nullable 한 컬럼을 다 추가해 보면 시간이 유사하게 1초 미만으로 걸린다.

이와 같이 12c 버전부터는 default 값을 가지는 컬럼 추가 작업이 개선되어 부담이 줄게 되었다.

 

3. 결론

default 값을 갖는 컬럼을 추가할 때 관리자는 내부에서 발생하는 update 때문에 작업에 대한 부담감이 항상 많았었다.

11g 버전에서 반쪽짜리로 not null 제약 조건을 줄 경우 이런 부담감을 없애 줬는데 

12c 버전에서는 모든 상황에서 부담감 없이 컬럼을 추가할 수 있도록 개선이 된 것이다.

 

버전이 올라가면서 이런 개선 사항들이 있어야 업그레이드 하는 맛이 있을 듯하다.

번호 제목 글쓴이 날짜 조회 수
34 Oracle Archive log 사용량 확인(GV$ARCHIVED_LOG) [1] 에밀리오 2016.08.04 11118
33 내가 돌린 SQL ID 찾기 [1] Talros 2016.05.12 8771
32 DBMS_SCHEDULER을 통해 OS 레벨(EXTERNAL)의 shell 수행하기 명품관 2017.04.05 5757
31 오라클 패치 정보를 조회할 수 있는 뷰 DBA_REGISTRY_SQLPATCH 명품관 2017.03.02 5454
30 Schema Password 복사 하기 Talros 2016.10.05 3255
29 Fixed Table에 대한 권한은 직접적으로 부여되지 않는다. 명품관 2016.08.26 2658
28 [12cR2 이상] 오브젝트 이름 30자이상 사용 가능 우뽕 2020.01.22 2301
27 Oracle Resource Limit를 이용한 간단한 Parameter Check (GV$RESOURCE_LIMIT) 에밀리오 2016.07.15 2230
26 Partition 추가의 계절 - Range Partition 추가시 알아 두어야할 부분 [1] 명품관 2015.12.03 2198
25 Kill Session Script (GV$SESSION) 에밀리오 2016.07.12 2118
24 Alert Log를 SQL 사용하여 보기 (X$DBGALERTEXT) [1] 에밀리오 2016.01.28 2006
23 Pga 메모리 설정관련 내용 [1] 우뽕 2021.03.05 1768
22 Alert log 에서 갑자기 패치 정보가 나타나는 현상 Talros 2019.09.23 1627
21 테이블 컬럼의 Default 값에 대한 흔적은 Dictionary에 계속 남게 된다. 명품관 2016.04.05 1578
20 Block Cleanout(블럭 클린아웃) 명품관 2016.09.23 1476
19 Schema password 재 사용 불가능 하게 하기 [1] Talros 2022.01.26 1260
18 DB option Enable / Disable 정리 방법 - Mos 참고 file 우뽕 2021.01.31 1204
17 Active Session History를 이용한 TOP SQL 분석 (GV$ACTIVE_SESSION_HISTORY) 에밀리오 2016.07.12 1189
16 RECO 프로세스 트레이스 발생 하면서 ORA-02019 에러 발생시 명품관 2021.01.12 983
15 SQL Plan Management(SPM) - 1 파라미터의 기능 확인 명품관 2020.03.19 966
위로