Postgresql에서 고정형과 가변형의 테이블 컬럼 순서에 따른 저장방식 0 0 3,436

by 지현명 [PostgreSQL 노하우/팁/자료] [2016.11.25 16:03:20]



참고 문서 : Troubleshooting PostgreSQL (Grouping columns the right way)

용어정의 :
--고정길이 데이터 타입 : 숫자형 데이터 타입과 char/nchar
--가변길이 데이터 타입 : varchar/nvarchar, text/ntext

테이블에 고정형과 가변형을 어떤 순서로 저장하는지/컬럼 순서가 바뀌면 어떻게 되는지 테스트 해봤습니다.
제목에 "Grouping columns the right way"게 되어 있는 거처럼 이미 하려고 하는 얘기는 나와 있습니다.ㅎㅎ

먼저 MS SQL은 어떻게 되어 있을까요?  MS-SQL 2014에서 테스트 해봤습니다.

CREATE TABLE T1 (  
 COL1 CHAR(1),
 COL2 VARCHAR(10),
 COL3 CHAR(1)
);

INSERT INTO T1 VALUES('a', 'ABC', 'b');

DBCC TRACEON(3604);   --DBCC PAGE 구문을 사용하기 위해
DBCC IND(TEST, T1, 1); --페이지 번호 찾기

DBCC PAGE(test, 1, 145, 3); --페이지 훔쳐보기
--결과는 고정형끼리  grouping해서 먼저 저장하고 그 뒤에 가변형을 순서대로 저장하고 있습니다.
--정원혁 강사님의 dbguide 강의나 책에 나와 있는 내용입니다.
--교육중에 강사님이 그래서 컬럼 순서 신경쓰지 말라고 하셨습니다.
0000000000000000:   30000600 61620300 00010010 00414243           0...ab.......ABC

Slot 0 Column 1 Offset 0x4 Length 1 Length (physical) 1 --4번째
COL1 = a                           

Slot 0 Column 2 Offset 0xd Length 3 Length (physical) 3 --16진수로 d위치에
COL2 = ABC                         

Slot 0 Column 3 Offset 0x5 Length 1 Length (physical) 1 --5번째
COL3 = b                           


그러면 Postgresql은 어떻게 하고 있는지 테스트 해보겠습니다.

#1. 컬럼 순서를 고정형과 가변형 섞어서
CREATE TABLE t_test (
v1 varchar(100),
i1 int,
v2 varchar(100),
i2 int,
v3 varchar(100),
i3 int
);

--한줄만 입력해서 heap table를 살펴 보겠습니다.
INSERT INTO t_test
SELECT 'abcd', 10, 'abcd', 20, 'abcd', 30
FROM generate_series(1, 1);

--MS SQL과는 다르게 테이블 컬럼 순서 그대로 저장합니다. 이렇게 되면 어떻게 되는지 뒤에서 설명드리겠습니다.

--create extension pageinspect;
SELECT * FROM heap_page_items(get_raw_page('t_test', 0));
\013abcd\000\000\000\012\000\000\000\013abcd\000\000\000\024\000\000\000\013abcd\000\000\000\036\000\000\000

--그럼 10000000 개 입력 해보고 해당 테이블의 사이즈 계산 해보겠습니다.
INSERT INTO t_test
SELECT 'abcd', 10, 'abcd', 20, 'abcd', 30
FROM generate_series(1, 10000000);

SELECT pg_size_pretty(pg_relation_size('t_test'));
651 MB <- 이정도 나오는군요...


#2. 고정형과 가변형을 Grouping 해서 테스트
CREATE TABLE t_test (
i1 int,
i2 int,
i3 int,
v1 varchar(100),
v2 varchar(100),
v3 varchar(100)
);

INSERT INTO t_test
SELECT 10, 20, 30, 'abcd', 'abcd', 'abcd'
FROM generate_series(1, 1);

--똑같은 데이터인데 위와 길이부터 우선 다릅니다. 순서만 바뀌었을 뿐인데 상당히 short하죠...
SELECT * FROM heap_page_items(get_raw_page('t_test', 0));
\012\000\000\000\024\000\000\000\036\000\000\000\013abcd\013abcd\013abcd

이 상태로 10000000개 입력하고 테이블 사이즈 보겠습니다.
INSERT INTO t_test
SELECT 10, 20, 30, 'abcd', 'abcd', 'abcd'
FROM generate_series(1, 10000000);

SELECT pg_size_pretty(pg_relation_size('t_test'));
574 MB <- 위에꺼보다 77MB가 적게 차지 합니다.

MS-SQL이 테이블 컬럼 순서에 상관없이 저장할때 고정형을 먼저 저장하는지에 대한 답변이 될듯 합니다.

이 테스트 결과를 기준으로 Postgresql에서 테이블 설계할때 참고..ㅎㅎ

테스트 결과 질문 : Postgresql 10 버전 올라가면 MS SQL처럼 테이블 저장할때 자동으로 해줄까요? 기대가 됩니다. ㅎㅎ

즐거운 주말 보내세요~^^

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입