AMAZON REDSHIFT. 데이터 압축2 - 압축 수행
AWS테이블(열)에 데이터 압축을 적용하는 방법은 두 가지가 있다. 테이블에 처음으로 데이터를 로드할 때 COPY 명령을 이용해 자동으로 인코딩 형식을 지정하도록 하는 방법과 CREATE TABLE 문으로 직접 인코딩 형식을 지정하는 방법이 있다. 여기서 권장되는 방법은 COPY 명령을 이용하는 것이다.
COPY 명령
COPY 명령으로 빈 테이블에 데이터가 적재될 때 자동으로 최적의 인코딩 형식이 적용된다. 이와 관련된 옵션은 다음과 같은 것들이 있다.
COMPUPDATE [ON | OFF]
압축 인코딩을 자동으로 적용할지 여부를 결정한다. COMPUPDATE 옵션을 생략했을 때는 테이블에 데이터가 없는 상태에서 테이블에 인코딩이 지정되지 않은 경우에 한해 자동으로 압축이 적용된다. COMPUPDATE 옵션을 ON으로 지정하면, 빈 테이블일 경우에 한해 이미 인코딩 유형이 지정되어 있어도 이를 무시하고 자동으로 최적의 인코딩 형식이 적용된다.
COMPROWS numrows
최적의 압축 인코딩을 결정하기 위해 조사할 데이터의 행 수를 지정한다. 원리는 비교적 간단하다. 여기서 지정한 행 수 만큼을 불러와 가능한 모든 인코딩 형식으로 압축해 보고, 가장 압축률이 좋은 인코딩 형식을 선택하게 된다.
행 수를 지정하지 않으면 조각(Slice) 마다 100,000개의 행이 적용된다. 행 수를 지정하면, 지정한 행 수를 총 조각수 만큼 나눈 숫자만큼 각 조각이 이용한다. 예를 들어, 클러스터에 총 4개의 조각이 있을 때, 행 수를 1,000,000으로 지정하면 각 조각마다 250,000개의 행을 이용한다.AWS Redshift 클러스터 유형별 조각수는 Amazon Redshift 클러스터 - 노드 유형에서 확인할 수 있다.
이제 실제 테이블을 만들어 COPY 명령을 이용한 예제를 살펴보자. 먼저 명시적으로 Raw 인코딩으로 테이블을 하나 생성하고, 별도로 인코딩 유형을 지정하지 않아 기본 인코딩 유형이 지정되도록 테이블을 하나 만들어 보자.
-- 명시적으로 압축하지 않도록 Raw 인코딩을 지정 create table customer ( c_custkey integer not null sortkey encode raw, c_name varchar(25) not null encode raw, c_address varchar(25) null encode raw, c_city varchar(10) null encode raw, c_nation varchar(15) null encode raw, c_region varchar(12) null encode raw, c_phone varchar(15) null encode raw, c_mktsegment varchar(10) not null encode raw ); -- 테이블을 생성할 때 압축 인코딩을 지정하지 않아 기본 인코딩 유형이 선택된다. create table customer_compressed ( c_custkey integer not null sortkey, c_name varchar(25) not null, c_address varchar(25) null, c_city varchar(10) null, c_nation varchar(15) null, c_region varchar(12) null, c_phone varchar(15) null, c_mktsegment varchar(10) not null );
이제 앞에서 만든 두 테이블의 열들의 압축 인코딩을 확인하기 위해 pg_table_def 시스템 카달로그 테이블을 쿼리한다. 쿼리 결과에서 encoding 열의 값을 확인하면 압축 인코딩 유형을 알 수 있다. 결과를 보면 명시적으로 Raw 인코딩을 지정한 열들은 encoding 열 값이 none 으로 나타나 압축을 하지 않고 있음을 알 수 있다. customer_compressed 테이블의 경우 기본 인코딩 유형이 선택 되었음을 확인할 수 있다.
-- 테이블의 인코딩 유형을 확인한다. select tablename, "column", type, encoding from pg_table_def where tablename in('customer','customer_compressed');
tablename | column | type | encoding |
customer | c_custkey | integer | none |
customer | c_name | character varying(25) | none |
customer | c_address | character varying(25) | none |
customer | c_city | character varying(10) | none |
customer | c_nation | character varying(15) | none |
customer | c_region | character varying(12) | none |
customer | c_phone | character varying(15) | none |
customer | c_mktsegment | character varying(10) | none |
customer_compressed | c_custkey | integer | none |
customer_compressed | c_name | character varying(25) | lzo |
customer_compressed | c_address | character varying(25) | lzo |
customer_compressed | c_city | character varying(10) | lzo |
customer_compressed | c_nation | character varying(15) | lzo |
customer_compressed | c_region | character varying(12) | lzo |
customer_compressed | c_phone | character varying(15) | lzo |
customer_compressed | c_mktsegment | character varying(10) | lzo |
앞에서 만든 두 테이블에 COPY 명령을 이용해 데이터를 적재하여 보자. customer 테이블은 compupdate off 옵션을 이용해 자동 압축이 일어나지 않아 압축되지 않은 형태로 데이터를 저장한다. 반면에 customer_compressed 테이블은 compupdate on 옵션을 이용해 최적의 압축 인코딩을 찾도록 했다.
-- 각 테이블에 데이터를 로드한다. 아래 데이터는 AWS 계정이 있으면 누구나 접근할 수 있다. copy customer from 's3://awssampledbuswest2/ssbgz/customer' credentials 'aws_access_key_id=*************;aws_secret_access_key=*************' gzip compupdate off -- 압축 인코딩을 자동으로 수행하지 않는다. region 'us-west-2'; copy customer_compressed from 's3://awssampledbuswest2/ssbgz/customer' credentials 'aws_access_key_id=*************;aws_secret_access_key=*************' gzip compupdate on -- 압축 인코딩을 자동으로 수행한다. region 'us-west-2';
데이터 적재가 완료되고 압축 인코딩의 변화를 살펴보기 위해 다시한번 pg_table_def 시스템 카달로그 테이블을 쿼리한다. 결과를 보면 customer_compressed 테이블의 압축 인코딩 유형이 처음과 바뀐것을 알 수 있다.
select tablename, "column", type, encoding from pg_table_def where tablename in('customer','customer_compressed');
tablename | column | type | encoding |
customer | c_custkey | integer | none |
customer | c_name | character varying(25) | none |
customer | c_address | character varying(25) | none |
customer | c_city | character varying(10) | none |
customer | c_nation | character varying(15) | none |
customer | c_region | character varying(12) | none |
customer | c_phone | character varying(15) | none |
customer | c_mktsegment | character varying(10) | none |
customer_compressed | c_custkey | integer | delta |
customer_compressed | c_name | character varying(25) | lzo |
customer_compressed | c_address | character varying(25) | lzo |
customer_compressed | c_city | character varying(10) | bytedict |
customer_compressed | c_nation | character varying(15) | bytedict |
customer_compressed | c_region | character varying(12) | bytedict |
customer_compressed | c_phone | character varying(15) | lzo |
customer_compressed | c_mktsegment | character varying(10) | bytedict |
마지막으로 두 테이블과 두 테이블의 각 열들의 크기(MB)를 비교해 보자.
-- 테이블의 크기를 비교해 보자. select "table", size from svv_table_info where "table" in('customer','customer_compressed');
table | size |
customer | 394 |
customer_compressed | 172 |
-- 열 크기를 비교해 보자. select p.name, b.col, count(*) from stv_blocklist b join stv_tbl_perm p on b.tbl = p.id and b.slice = p.slice where p.name in ('customer', 'customer_compressed') and b.col < 8 group by p.name, b.col order by 1,2
name | col | count |
customer | 0 | 14 |
customer | 1 | 66 |
customer | 2 | 60 |
customer | 3 | 46 |
customer | 4 | 38 |
customer | 5 | 36 |
customer | 6 | 60 |
customer | 7 | 40 |
customer_compressed | 0 | 6 |
customer_compressed | 1 | 16 |
customer_compressed | 2 | 56 |
customer_compressed | 3 | 6 |
customer_compressed | 4 | 6 |
customer_compressed | 5 | 6 |
customer_compressed | 6 | 36 |
customer_compressed | 7 | 6 |
테이블은 대략 절반 정도로 줄어 들었으며, 4번째 열(col=3)인 c_city 열은 원본이 46MB에서 6MB로 줄어 원본대비 13%로 줄어들었다.
인코딩 유형 지정
CREATE TABLE 문으로 테이블을 생성하거나 ALTER TABLE 문으로 새로운 열을 추가할 때 인코딩 유형을 지정할 수 있다. 다만 이미 데이터가 있는 테이블이려면 인코딩 유형을 변경할 수 없다. 다음은 cusomter 테이블을 만들고, 나이(age) 열을 추가할 때 인코딩 유형을 지정하는 예제이다.
create table customer ( c_custkey integer not null encode delta, c_name varchar(25) not null encode zstd, c_address varchar(25) null encode zstd, c_city varchar(10) null encode bytedict, c_nation varchar(15) null encode bytedict, c_region varchar(12) null encode bytedict, c_phone varchar(15) null encode zstd, c_mktsegment varchar(10) not null encode bytedict ); alter table customer add column c_age int null encode mostly8;
'AWS' 카테고리의 다른 글
AMAZON REDSHIFT. COPY 명령2 - 최적화 (0) | 2018.08.17 |
---|---|
AMAZON REDSHIFT. COPY 명령1 - 기본내용 (0) | 2018.08.16 |
AMAZON REDSHIFT. 데이터 압축3 - 관리 (0) | 2018.08.14 |
AMAZON REDSHIFT. 데이터 압축1 - 압축 유형 (0) | 2018.08.06 |
Power BI에서 Amazon Redshift 연결을 위한 구성 (0) | 2018.08.06 |