CHAR 타입과 VARCHAR2 타입을 함께 사용하면 의도치 않은 결과가 반환될 수 있다.
테스트를 위해 아래와 같이 테이블을 생성하자. t1 테이블의 c1 칼럼은 CHAR 타입, c2 칼럼은 VARCHAR2 타입이고, 자릿수는 2로 동일하다. A는 동일한 값, B는 상이한 값을 입력했다.
1 2 3 4 5 6 7 8 9 |
-- 1 CREATE TABLE t1 (c1 CHAR (2), c2 VARCHAR2(2)); CREATE INDEX t1_x1 ON t1 (c1); CREATE INDEX t1_x2 ON t1 (c2); INSERT INTO t1 VALUES ( 'A' , 'A' ); INSERT INTO t1 VALUES ( 'B' , 'B ' ); COMMIT ; |
쿼리 2-1에서 B가 동일한 값으로 평가되었다. 쿼리 2-2처럼 TRIM 함수는 사용해야 의도한 결과를 얻을 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
-- 2-1 SELECT c1, c2 FROM t1 WHERE c1 = c2; C1 C2 -- -- B B 1개의 행이 선택되었습니다. -- 2-2 SELECT c1, c2 FROM t1 WHERE TRIM (c1) = c2; C1 C2 -- -- A A 1개의 행이 선택되었습니다. |
저장 공간 측면에서도 CHAR 타입보다 VARCHAR2 타입이 유리하다. 테스트를 위해 아래와 같이 테이블을 생성하자. 칼럼 크기를 t1, t2 테이블은 10, t3, t4 테이블은 100으로 생성하고, 크기가 10인 값을 100만건 입력했다.
1 2 3 4 5 6 7 8 9 10 11 |
-- 3 CREATE TABLE t1 (c1 CHAR (10)); CREATE TABLE t3 (c1 VARCHAR2(10)); CREATE TABLE t2 (c1 CHAR (100)); CREATE TABLE t4 (c1 VARCHAR2(100)); INSERT INTO t1 SELECT LPAD ( 'X' , 10, 'X' ) AS c1 FROM XMLTABLE ( '1 to 1000000' ); INSERT INTO t2 SELECT * FROM t1; INSERT INTO t3 SELECT * FROM t1; INSERT INTO t4 SELECT * FROM t1; COMMIT ; |
t1, t2 테이블은 18MB로 크기가 동일하다. t3 테이블은 120MB로 생성된다. CHAR 타입은 남는 공간을 공백으로 채우기 때문이다. t4 테이블은 t1, t2 테이블과 크기가 동일하다. 테스트 결과에서 알 수 있듯 CHAR 타입은 가급적 사용하지 않은 편이 바람직하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-- 4 SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name IN ( 'T1' , 'T2' , 'T3' , 'T4' ); SEGMENT_NAME BYTES BLOCKS EXTENTS ------------ --------- ------ ------- T1 18874368 2304 33 T2 18874368 2304 33 T3 125829120 15360 86 T4 18874368 2304 33 4 개의 행이 선택되었습니다. |
'Oracle > Administration' 카테고리의 다른 글
CLOB #5 - ENABLE STORAGE IN ROW (0) | 2019.02.09 |
---|---|
Covered 인덱스와 인덱스 브랜치 블록 (0) | 2019.01.06 |
Intra-block row chaining (0) | 2018.12.28 |
NVARCHAR 타입의 부작용 (0) | 2018.12.28 |
PK 제약조건과 NOT NULL 제약조건 (0) | 2018.12.27 |