OS환경 : Oracle Linux 5.8, 6.8, 7.3 (64bit)
DB 환경 : Oracle Database 10.2.0.4, 11.2.0.4, 12.2.0.1(메인), 18.3.0.0
방법 : 오라클 테이블 compress 정리(10g, 11g, 12c, 18c)
1. 기본적인 이론
Oracle Database 11g의 압축기술
오라클은 9i부터 11g까지 relational data를 처리하기 위한 특화된 알고리즘을 사용
database block 내, 다수의 column의 중복된 값을 제거하여 compression을 수행
Compress 된 block은 compression과 관련된 metadata를 symbol table에 저장
이 table는 block의 상단에 위치해 있다.
Symbol table이 각 block에 있다는 점만 제외하면 uncompressed table과 compressed table의 차이는 거의 없다
11g 이전까지는 Direct Loading이나 CTAS등과 같은 작업을 통해 벌크 로딩을 수행하면서 데이터를 압축할 수 있었지만, 벌크로 로딩하면서 압축된 데이터에 대해 DML 작업이 발생하면 이후부터는 압축이 풀린 상태로 관리되었기 때문에 일반적인 데이터 작업에서는 압축을 활용할 수 없었다.
11g에 와서는 일반적인 DML 작업에 대해서도 압축이 가능해졌기 때문에, OLTP 시스템에서 데이터에 대한 변경이 발생하는 테이블에 대해서도 압축을 사용할 수 있게 되었다.
2. 10g와 11g의 Table Compression 비교
10g의 Table Compression
Compression 시기
새로운 data를 Bulk insert나 bulk load할 때 compression을 사용할 수 있다.
batch process로 data를 load하는 DW환경에 이상적이다.
- Direct path SQL*Loader
- CREATE TABLE AS SELECT (CTAS) statements
- Parallel INSERT (or serial INSERT with an APPEND hint) statements
기존의 data는 ALTER TABLE과 MOVE statement로 compress할 수 있다.
Note
Compression과 관련된 overhead는 bulk loading 중에 최대가 된다.
또한, Compress된 table에 DML을 사용할 수 있지만 bulk insertion이나 bulk loading을 사용하지 않은 data는 compress되지 않는다.
결국 한 table안에 compress된 부분과 uncompress된 부분이 공존하게 된다.
Uncompressed table과 비교해서는 Update을 제외한 다른 DML에서는 처리속도상의 차이가 거의 없다.
- OLTP 보다 DW에 유리하다.
- Enterprise Edition에 포함.
11g의 Table Compression
Compression 시기
새로운 data를 Bulk insert나 bulk load 또는 그냥 insert, update 할 때 compression을 사용할 수 있다.
- Direct path SQL*Loader
- CREATE TABLE AS SELECT (CTAS) statements
- Parallel INSERT (or serial INSERT with an APPEND hint) statements
- Single-row or array inserts
- Single-row or array updates
기존의 data는 ALTER TABLE과 MOVE statement로 compress할 수 있다.
Note
Compression과 관련된 overhead는 bulk loading 중에 최대가 된다.
또한, Compress된 table에 모든 DML을 사용할 수 있다.
Uncompressed table과 비교해서는 Update을 제외한 다른 DML에서는 처리속도상의 차이가 거의 없다.
- OLTP와 DW 환경에 둘 다 적용 가능하다.
새로운 data를 write할 때마다 block을 compress하는 방식이 아니라 내부적인 threshold를 넘으면 batch mode로 한번에 compress하기 때문에 OLTP에 적용 가능하다.
- Oracle Advanced Compression Option에 포함. (for OLTP)
11g Enterprise Edition에서는 10g 기술을 사용할 수 있다. (for DW)
3. Compress 옵션 별 특징
Basic Compression의 특징
- 모든 Enterprise Edition version Oracle에서 사용가능함
- Direct Path IO 작업으로 생성된 Block만 압축됨[Compressed Block]
- 하나의 Segment에 여러 형태의 Block이 혼재 할수 있음
- 즉 Compressed Block[Direct Path IO 작업] 과 Uncompressed Block[Conventional Path IO 작업] 이 혼재됨
- 하나의 Block에 일부는 Compressed, 일부는 Uncompressed 인 경우도 존재 할수 있음
OLTP Compression : COMPRESS FOR OLTP 의 특징
- Oracle ACO 라고 하는 Advanced Compression Option 이 활성화된 시스템. ==> 1. DB option check
- Advanced Compression Option은 비용이 발생하고, 매우 고가의 DB Option 임
- Conventional Path IO 작업시에도 압축 가능
4. 옵션별 압축률 및 COMP_TYPE 확인 테스트
데이터 삽입용 임시 테이블 생성
1
2
3
|
CREATE TABLE MAXTEST(COLA VARCHAR2(20), COLB NUMBER, COLC NUMBER,
COLD VARCHAR2(30), COLE VARCHAR2(30), COLF VARCHAR2(30),
COLG NUMBER, COLH VARCHAR2(30), COLI VARCHAR2(30));
|
임시 테이블 데이터 삽입
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
DECLARE
TYPE tbl_ins IS TABLE OF MAXTEST%ROWTYPE INDEX BY BINARY_INTEGER;
w_ins tbl_ins;
BEGIN
FOR i IN 1..1400000 LOOP
w_ins(i).COLA :=i;
w_ins(i).COLB :=300000;
w_ins(i).COLC :=99;
w_ins(i).COLD :='DDDDDDDDDDDDDDDD';
w_ins(i).COLE :='EEEEEEEEEEEEEEEE';
w_ins(i).COLF :='FFFFFFFFFFFFFFFF';
w_ins(i).COLG :=9999999;
w_ins(i).COLH :='HHHHHHHHHHHHHHHHHHHHHHHHHH';
w_ins(i).COLI :='IIIIIIIIIIIIIIIIIIIIIIIIII';
END LOOP;
FORALL i in 1..1400000 INSERT INTO MAXTEST VALUES w_ins(i);
COMMIT;
END;
/
|
임시테이블 count 조회
1
2
3
4
5
|
select count(*) from MAXTEST ;
COUNT(*)
----------
1400000
|
압축 테스트 테이블 삭제
1
2
3
|
drop table test_nocomp purge ;
drop table test_basic purge ;
drop table test_oltp purge ;
|
압축 테스트 테이블 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
create table test_nocomp
tablespace users
as
select *
from MAXTEST
where 1 = 2 ;
create table test_basic
tablespace users
compress basic
as
select *
from MAXTEST
where 1 = 2 ;
create table test_oltp
tablespace users
compress for oltp
as
select *
from MAXTEST
where 1 = 2 ;
|
테이블 압축 레벨 체크
1
2
3
4
|
col table_name for a20
SELECT table_name, compression, compress_for
FROM user_tables
where table_name like 'TEST%';
|
11g의 경우 OLTP는 COMPRESS_FOR이 OLTP로 표시됨
1
2
3
4
5
|
TABLE_NAME COMPRESSION COMPRESS_FOR
----------- ----------- -----------
TEST_OLTP ENABLED OLTP
TEST_NOCOMP DISABLED (null)
TEST_BASIC ENABLED BASIC
|
12c이상 버전의 경우 COMPRESS_FOR이 ADVANCED로 표시됨
1
2
3
4
5
|
TABLE_NAME COMPRESS COMPRESS_FOR
----------- ----------- -----------
TEST_BASIC ENABLED BASIC
TEST_NOCOMP DISABLED (null)
TEST_OLTP ENABLED ADVANCED
|
압축 테스트 테이블 데이터 삽입
1
2
3
4
5
6
7
8
9
|
insert into test_nocomp
select * from MAXTEST ;
insert into /*+ APPEND */ test_basic
select * from MAXTEST ;
insert into test_oltp
select * from MAXTEST ;
commit;
|
* 위 구문이 아닌 insert /*+ APPEND */ into 로 사용해야함
압축 테스트 테이블 count 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
select count(*) from test_nocomp ;
COUNT(*)
----------
1400000
select count(*) from test_basic ;
COUNT(*)
----------
1400000
select count(*) from test_oltp ;
COUNT(*)
----------
1400000
|
압축 테스트 테이블 용량 조회
1
2
3
4
5
6
7
8
9
10
11
|
col segment_name for a20
col segment_type for a20
select segment_name, segment_type, blocks, bytes
from user_segments
where segment_type = upper('table')
and segment_name like upper('test%');
SEGMENT_NAME SEGMENT_TYPE BLOCKS BYTES
------------- ------------- -------- ----------
TEST_NOCOMP TABLE 25600 209715200
TEST_BASIC TABLE 23552 192937984
TEST_OLTP TABLE 2688 22020096
|
자료의 압축 TYPE 확인
DBMS_COMPRESSION.GET_COMPRESSION_TYPE 이용
1 = No compression
2 = Advanced compression level
4096 = Basic compression level
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
34
35
36
37
|
col rowid format a18
col owner format a10
col object_name format a30
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_NOCOMP', rowid ) comp_type
from TEST_NOCOMP
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeDAAEAAAACDAAA 116 1
AAAFeDAAEAAAACDAAB 117 1
AAAFeDAAEAAAACDAAC 118 1
AAAFeDAAEAAAACDAAD 119 1
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_BASIC', rowid ) comp_type
from TEST_BASIC
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeEAAEAAAACLAAA 129 1
AAAFeEAAEAAAACLAAB 130 1
AAAFeEAAEAAAACLAAC 131 1
AAAFeEAAEAAAACLAAD 132 1
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_OLTP', rowid ) comp_type
from TEST_OLTP
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeFAAEAAAACTAAA 1293 2
AAAFeFAAEAAAACTAAB 1294 2
AAAFeFAAEAAAACTAAC 1295 2
AAAFeFAAEAAAACTAAD 1296 2
|
1차 정리
압축률 테스트
TEST_NOCOMP : 209,715,200 Byte
TEST_BASIC : 192,937,984 Byte
TEST_OLTP : 22,020,096 Byte
압축률 비교 : TEST_NOCOMP < TEST_BASIC < TEST_OLTP
#BASIC 테이블 조회 시 COMP_TYPE이 1로 나오는걸 기억 할것(정상적인 BASIC의 COMP_TYPE는 4096임(12c이상))
MOVE 명령으로 다시 각각 압축
1
2
3
|
ALTER TABLE TEST_NOCOMP MOVE NOCOMPRESS;
ALTER TABLE TEST_BASIC MOVE COMPRESS BASIC;
ALTER TABLE TEST_OLTP MOVE COMPRESS FOR OLTP;
|
압축 테스트 테이블 용량 조회
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
col segment_name for a20
col segment_type for a20
select segment_name, segment_type, blocks, bytes
from user_segments
where segment_type = upper('table')
and segment_name like upper('test%');
MOVE 후
SEGMENT_NAME SEGMENT_TYPE BLOCKS BYTES
------------- ------------- -------- ----------
TEST_NOCOMP TABLE 25600 209715200
TEST_BASIC TABLE 2432 19922944
TEST_OLTP TABLE 2688 22020096
MOVE 전과 비교
SEGMENT_NAME SEGMENT_TYPE BLOCKS BYTES
------------- ------------- -------- ----------
TEST_NOCOMP TABLE 25600 209715200
TEST_BASIC TABLE 23552 192937984
TEST_OLTP TABLE 2688 22020096
|
자료의 압축 TYPE 확인
DBMS_COMPRESSION.GET_COMPRESSION_TYPE 이용
1 = No compression
2 = Advanced compression level
4096 = Basic compression level
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
34
35
36
|
col rowid format a18
col owner format a10
col object_name format a30
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_NOCOMP', rowid ) comp_type
from TEST_NOCOMP
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeGAAEAAAMsDAAA 116 1
AAAFeGAAEAAAMsDAAB 117 1
AAAFeGAAEAAAMsDAAC 118 1
AAAFeGAAEAAAMsDAAD 119 1
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_BASIC', rowid ) comp_type
from TEST_BASIC
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeHAAEAAAACDAAA 129 4096
AAAFeHAAEAAAACDAAB 130 4096
AAAFeHAAEAAAACDAAC 131 4096
AAAFeHAAEAAAACDAAD 132 4096
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_OLTP', rowid ) comp_type
from TEST_OLTP
where rownum < 5 ;
ROWID COLA COMP_TYPE
------------------ -------------------- ---------
AAAFeIAAEAAAACLAAA 1293 2
AAAFeIAAEAAAACLAAB 1294 2
AAAFeIAAEAAAACLAAC 1295 2
AAAFeIAAEAAAACLAAD 1296 2
|
2차 정리
압축률 테스트
TEST_NOCOMP : 209,715,200 Byte
TEST_BASIC : 19,922,944 Byte
TEST_OLTP : 22,020,096 Byte
압축률 비교 : TEST_NOCOMP < TEST_OLTP < TEST_BASIC
#BASIC 테이블도 MOVE 명령을 통해 다시 압축됨
#BASIC 테이블 조회 시 12c이상에서는 COMP_TYPE이 정상적으로 4096로 표시됨
#BASIC 테이블 조회 시 11gR2까지는 BASIC의 COMP_TYPE이 따로 없어서 2로 나옴
#1차 정리에서 COMP_TYPE이 1로 표시되었던 것은 Basic Compression의 특징 때문임(11g,12c공통)
- 아래 테스트로 확인가능
BASIC COMPRESS의 특징 확인 테스트
압축 테스트 테이블 생성
1
2
3
4
5
6
|
create table TEST_BASIC2
tablespace users
compress basic
as
select *
from MAXTEST
where 1 = 2 ;
|
압축 테스트 테이블 데이터 삽입1
1
2
|
insert into /*+ APPEND */ TEST_BASIC2
select * from MAXTEST where rownum<=100;
|
* 위 구문이 아닌 insert /*+ APPEND */ into 로 사용해야함
자료의 압축 TYPE 확인
1
2
3
4
5
6
7
8
9
|
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_BASIC2', rowid ) comp_type
from TEST_BASIC2
where rownum < 4 ;
ROWID COLA COMP_TYPE
---------------- ------ --------------
AAASb3AAHAAAGeNAAA 1 1
AAASb3AAHAAAGeNAAB 2 1
AAASb3AAHAAAGeNAAC 3 1
|
MOVE 명령으로 다시 COMPRES
1
|
ALTER TABLE TEST_BASIC2 MOVE COMPRESS BASIC;
|
MOVE 명령을 통해 일반 insert 로 삽입된 데이터를 압축함
압축 테스트 테이블 데이터 삽입2
1
2
|
insert into /*+ APPEND */ TEST_BASIC2
select * from MAXTEST where rownum<=100;
|
* 위 구문이 아닌 insert /*+ APPEND */ into 로 사용해야함
자료의 압축 TYPE 확인
1
2
3
4
5
6
7
8
9
10
11
12
|
select rowid, COLA, dbms_compression.get_compression_type(user, 'TEST_BASIC2', rowid ) comp_type
from TEST_BASIC2;
중반쯤으로 내리면 COMP_TYPE가 4096과 1이 혼재되어있는것을 확인 가능함
11gR2의 경우 COMP_TYPE가 2와 1이 혼재되어있는것을 확인 가능함
ROWID COLA COMP_TYPE
------------------- ---------- -----------
AAASb3AAHAAAGeLABr 98 4096
AAASb3AAHAAAGeLABs 99 4096
AAASb3AAHAAAGeLABt 100 4096
AAASb3AAHAAAGeNAAA 1 1
AAASb3AAHAAAGeNAAB 2 1
AAASb3AAHAAAGeNAAC 3 1
|
하나의 table에 일부는 Compressed(4096), 일부는 Uncompressed(1) 인 경우를 확인 가능함
처음에는 압축하지 않고 MOVE명령을 실행한 뒤부터 압축이 된다는걸 알 수있음
+MOVE 명령어 이용 시 Exclusive Table Lock 이 발생하니 주의 해야함
lock 확인 테스트
데이터 삽입
1
2
3
|
insert into /*+ APPEND */ TEST_BASIC2
select * from MAXTEST ;
commit;
|
* 위 구문이 아닌 insert /*+ APPEND */ into 로 사용해야함
(세션1) MOVE 실행(과 동시에 세션2에서 쿼리 조회)
1
|
ALTER TABLE TEST_BASIC2 MOVE COMPRESS BASIC;
|
(세션2) lock 조회
1
2
3
4
5
6
7
|
SELECT DO.OBJECT_NAME, DO.OWNER, DO.OBJECT_TYPE, DO.OWNER,
VO.XIDUSN, VO.SESSION_ID, VO.LOCKED_MODE
FROM V$LOCKED_OBJECT VO, DBA_OBJECTS DO
WHERE VO.OBJECT_ID = DO.OBJECT_ID;
OBJECT_NAME OWNER OBJECT_TYPE OWNER XIDUSN SESSION_ID LOCKED_MODE
----------- ------- --------- -------- ------- ---------- -----------
TEST_BASIC2 SYS TABLE SYS 10 68 6
|
lock 발생 확인 가능 LOCKED_MODE 6은 Exclusive (X): Exclusive Table Lock 임
추가적으로 11g는 basic 에 해당하는 상수가 없기때문에
테스트처럼 1로 표시되는것(https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_compress.htm)
12c 이상은 basic에 해당하는 상수가 생겨서 4096으로 표시됨(https://docs.oracle.com/database/121/ARPLS/d_compress.htm#ARPLS236)
+
12c 이후부터는 Advanced compress 가 추가되었는데 위에서 작성한
단순히 oltp 옵션으로 생성했을때 advanced로 표시 되기도 하지만 아래와 같이
ROW STORE COMPRESS ADVANCED 라는 옵션을 주고 생성할수도 있음
(또한 Exa장비 전용 옵션도 생김 COLUMN STORE COMPRESS FOR QUERY과 COLUMN STORE COMPRESS FOR ARCHIVE 옵션)
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
임시 테이블 생성
drop table maxtest purge;
CREATE TABLE MAXTEST(COLA VARCHAR2(20), COLB NUMBER, COLC NUMBER,
COLD VARCHAR2(30), COLE VARCHAR2(30), COLF VARCHAR2(30),
COLG NUMBER, COLH VARCHAR2(30), COLI VARCHAR2(30)) tablespace imsi;
벌크 인서트로 삽입
DECLARE
TYPE tbl_ins IS TABLE OF MAXTEST%ROWTYPE INDEX BY BINARY_INTEGER;
w_ins tbl_ins;
BEGIN
FOR i IN 1..1400000 LOOP
w_ins(i).COLA :=i;
w_ins(i).COLB :=300000;
w_ins(i).COLC :=99;
w_ins(i).COLD :='DDDDDDDDDDDDDDDD';
w_ins(i).COLE :='EEEEEEEEEEEEEEEE';
w_ins(i).COLF :='FFFFFFFFFFFFFFFF';
w_ins(i).COLG :=9999999;
w_ins(i).COLH :='HHHHHHHHHHHHHHHHHHHHHHHHHH';
w_ins(i).COLI :='IIIIIIIIIIIIIIIIIIIIIIIIII';
END LOOP;
FORALL i in 1..1400000 INSERT INTO MAXTEST VALUES w_ins(i);
COMMIT;
END;
/
COMPRESS 옵션없이 테이블 생성
CREATE TABLE TEST_NOCOMP
TABLESPACE IMSI
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
BASIC 옵션으로 테이블 생성
CREATE TABLE TEST_BASIC
TABLESPACE IMSI
COMPRESS BASIC
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
OLTP 옵션으로 테이블 생성
CREATE TABLE TEST_OLTP
TABLESPACE IMSI
COMPRESS FOR OLTP
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
ADVANCED 옵션으로 테이블 생성
CREATE TABLE TEST_ADVAN
TABLESPACE IMSI
ROW STORE COMPRESS ADVANCED
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
QUERY 옵션으로 테이블 생성(Exa Only)
CREATE TABLE TEST_QUERY
TABLESPACE IMSI
COLUMN STORE COMPRESS FOR QUERY
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
ARCHIVE 옵션으로 테이블 생성(Exa Only)
CREATE TABLE TEST_ARCH
TABLESPACE IMSI
COLUMN STORE COMPRESS FOR ARCHIVE
AS
SELECT *
FROM MAXTEST
WHERE 1 = 2 ;
테이블 압축 레벨 확인
col table_name for a20
SELECT table_name, compression, compress_for
FROM user_tables
where table_name like 'TEST%';
TABLE_NAME COMPRESS COMPRESS_FOR
-------------------- -------- ------------------------------
TEST_NOCOMP ENABLED (null)
TEST_BASIC ENABLED BASIC
TEST_OLTP ENABLED ADVANCED
TEST_ADVAN ENABLED ADVANCED
TEST_QUERY ENABLED QUERY HIGH
TEST_ARCH ENABLED ARCHIVE LOW
|
참조 :
https://positivemh.tistory.com/927
https://positivemh.tistory.com/929
https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_compress.htm
https://docs.oracle.com/database/121/ARPLS/d_compress.htm#ARPLS236
https://cafe.naver.com/prodba/49971
https://docs.oracle.com/database/121/ADMIN/tables.htm#ADMIN11629
'ORACLE > Admin' 카테고리의 다른 글
오라클 reorg, hwm, shrink, move 설명 및 테스트 (6) | 2018.12.26 |
---|---|
오라클 기초 정리 (4) | 2018.12.19 |
오라클 Hot backup시 변경이 발생한다면? (4) | 2018.12.17 |
오라클 Primary Keys 설정 (0) | 2018.12.12 |
오라클 create table 구문 옵션별 설명 (0) | 2018.12.12 |