압축 인코딩 - Amazon Redshift

압축 인코딩

행을 테이블에 추가할 때 데이터 값의 열에 적용되는 압축 형식은 압축 인코딩에 따라 결정됩니다.

ENCODE AUTO는 테이블의 기본값입니다. 테이블이 ENCODE AUTO로 설정되어 있는 경우 Amazon Redshift는 테이블의 모든 열에 대한 압축 인코딩을 자동으로 관리합니다. 자세한 내용은 CREATE TABLEALTER TABLE 단원을 참조하세요.

그러나 테이블의 열에 압축 인코딩을 지정하면 테이블이 더 이상 ENCODE AUTO로 설정되지 않습니다. Amazon Redshift는 더 이상 테이블의 모든 열에 대한 압축 인코딩을 자동으로 관리하지 않습니다.

CREATE TABLE을 사용하는 경우 테이블의 열에 대한 압축 인코딩을 지정하면 ENCODE AUTO가 비활성화됩니다. ENCODE AUTO가 비활성화된 경우 Amazon Redshift는 다음과 같이 ENCODE 유형을 지정하지 않은 열에 압축 인코딩을 자동으로 할당합니다.

  • 정렬 키로 정의된 열은 RAW 압축이 할당됩니다.

  • BOOLEAN, REAL 또는 DOUBLE PRECISION 데이터 형식으로 정의된 열은 RAW 압축이 할당됩니다.

  • SMALLINT, INTEGER, BIGINT, DECIMAL, DATE, TIMESTAMP 또는 TIMESTAMPTZ 데이터 형식으로 정의된 열에는 AZ64 압축이 할당됩니다.

  • CHAR 또는 VARCHAR 데이터 형식으로 정의된 열에는 LZO 압축이 할당됩니다.

테이블을 만든 후 ALTER TABLE을 사용하여 테이블의 인코딩을 변경할 수 있습니다. ALTER TABLE을 사용하여 ENCODE AUTO를 비활성화하면 Amazon Redshift는 더 이상 열의 압축 인코딩을 자동으로 관리하지 않습니다. 모든 열은 사용자가 변경하거나 ENCODE AUTO를 다시 활성화하기 전까지는 ENCODE AUTO를 비활성화한 시점의 압축 인코딩 유형을 그대로 유지합니다.

Amazon Redshift는 다음과 같은 압축 인코딩을 지원합니다.

Raw

Raw 인코딩은 정렬 키로 지정되는 열과 BOOLEAN, REAL 또는 DOUBLE PRECISION 데이터 형식으로 정의되는 열에서 기본 인코딩입니다. Raw 인코딩에서는 데이터가 압축되지 않은 원시 형태로 저장됩니다.

AZ64

AZ64는 Amazon에서 높은 압축비와 개선된 쿼리 처리 기능을 달성하도록 설계된 독점 압축 인코딩 알고리즘입니다. 핵심적으로, AZ64 알고리즘은 더 작은 그룹의 데이터 값을 압축하고 병렬 처리를 위해 단일 명령, 다중 데이터(SIMD) 명령을 사용합니다. AZ64를 사용하면 스토리지를 크게 절약하고 숫자, 날짜, 시간 데이터 유형에서 뛰어난 성능을 달성할 수 있습니다.

다음 데이터 유형의 CREATE TABLE 및 ALTER TABLE 문을 사용하여 열을 정의할 때 AZ64를 압축 인코딩으로 사용할 수 있습니다.

  • SMALLINT

  • INTEGER

  • BIGINT

  • DECIMAL

  • 날짜

  • TIMESTAMP

  • TIMESTAMPTZ

Byte-dictionary

Byte Dictionary 인코딩에서는 디스크에 저장되어 있는 열 값 블록마다 고유 값의 딕셔너리가 별도로 생성됩니다. Amazon Redshift 디스크 블록은 1MB를 차지합니다. 딕셔너리에는 1바이트 값이 최대 256개까지 원래 데이터 값에 대한 인덱스로 저장됩니다. 단일 블록에 저장되는 값이 256개를 넘어가면 추가 값이 압축되지 않은 원시 형태로 블록에 작성됩니다. 이 프로세스가 각 디스크 블록마다 반복됩니다.

이 인코딩은 카디널리티가 낮은 문자열 열에서 매우 효과적입니다. 그래서 열의 데이터 도메인이 256개의 고유 값보다 적을 때 가장 적합합니다.

BYTEDICT로 인코딩된 문자열 데이터 유형(CHAR 및 VARCHAR)이 있는 열의 경우 Amazon Redshift는 압축된 데이터를 대상으로 직접 작동하는 벡터화된 스캔 및 조건자 평가를 수행합니다. 이러한 스캔은 하드웨어별 단일 명령과 다중 데이터(SIMD) 명령을 사용하여 병렬 처리를 수행합니다. 이렇게 하면 문자열 열 스캔 속도가 크게 향상됩니다. Byte-Dictionary 인코딩은 CHAR/VARCHAR 열에 긴 문자열이 저장되어 있는 경우에 특히 공간 효율적입니다.

예를 들어 테이블에 CHAR(30) 데이터 형식의 COUNTRY 열이 있다고 가정하겠습니다. 데이터가 로드되면서 Amazon Redshift가 딕셔너리를 생성한 후 인덱스 값으로 COUNTRY 열을 채웁니다. 딕셔너리에 고유의 인덱스 값이 저장되고, 테이블 자체에는 해당하는 값의 1바이트 서브스크립트만 저장됩니다.

참고

고정 길이 문자 열(column)에서는 후행 공백이 저장됩니다. 따라서 CHAR(30) 열에서 Byte-Dictionary 인코딩을 사용할 때는 모든 값이 압축되어 29바이트의 스토리지를 절약합니다.

다음 표는 COUNTRY 열의 딕셔너리를 나타낸 것입니다.

고유 데이터 값 딕셔너리 인덱스 크기(고정 길이, 값 1개당 30바이트)
England 0 30
United States of America 1 30
Venezuela 2 30
Sri Lanka 3 30
Argentina 4 30
Japan 5 30
합계 180

다음 표는 COUNTRY 열의 값을 나타낸 것입니다.

원래 데이터 값 원래 크기(고정 길이, 값 1개당 30바이트) 압축된 값(인덱스) 새로운 크기(바이트)
England 30 0 1
England 30 0 1
United States of America 30 1 1
United States of America 30 1 1
Venezuela 30 2 1
Sri Lanka 30 3 1
Argentina 30 4 1
Japan 30 5 1
Sri Lanka 30 3 1
Argentina 30 4 1
합계 300 10

위 예에서 압축된 전체 크기는 다음과 같은 방법으로 계산합니다. 딕셔너리에 저장되는 입력 항목이 6개이고(6 * 30 = 180), 테이블에는 1바이트로 압축된 값 10개가 저장되어 전체 크기는 190바이트가 됩니다.

Delta

Delta 인코딩은 날짜/시간 열에 매우 유용합니다.

Delta 인코딩은 열에서 서로 인접한 값 사이의 차이를 기록하여 데이터를 압축합니다. 이 차이는 디스크에 저장되어 있는 열 값 블록마다 별도의 딕셔너리에 기록됩니다. Amazon Redshift 디스크 블록은 1MB를 차지합니다. 예를 들어 열에 1에서 10까지의 순서로 10개의 정수가 포함되어 있다고 가정합니다. 첫 번째는 4바이트 정수(1바이트 플래그 포함)로 저장됩니다. 다음 9개는 각각 값이 1인 바이트로 저장되어 이전 값보다 1이 큼을 나타냅니다.

Delta 인코딩은 다음 2가지 유형이 있습니다.

  • DELTA는 차이를 1바이트 값으로 기록합니다(8비트 정수).

  • DELTA32K는 차이를 2바이트 값으로 기록합니다(16비트 정수).

열에 있는 대부분의 값을 단일 바이트로 압축할 수 있다면 1바이트 변형이 매우 효과적입니다. 그러나 델타가 더 크면 최악의 경우 이 인코딩이 압축되지 않은 데이터를 저장하는 것보다 효과가 떨어질 수 있습니다. 16비트 버전에도 비슷한 로직이 적용됩니다.

두 값의 차이가 1바이트 범위(DELTA) 또는 2바이트 범위(DELTA32K)를 벗어나면 1바이트 플래그가 선행하면서 원래 값 전체가 저장됩니다. 여기에서 1바이트 범위란 -127~127을, 2바이트 범위란 -32~32K를 의미합니다.

다음 표는 숫자 열에서 Delta 인코딩의 압축 방식을 나타낸 것입니다.

원래 데이터 값 원래 크기(바이트) 차이(델타) 압축된 값 압축된 크기(바이트)
1 4 1 1+4(플래그 + 실제 값)
5 4 4 4 1
50 4 45 45 1
200 4 150 150 1+4(플래그 + 실제 값)
185 4 -15 -15 1
220 4 35 35 1
221 4 1 1 1
합계 28 15
LZO

LZO 인코딩은 높은 압축비로 우수한 성능을 제공하기 때문에 긴 문자열이 저장되는 CHAR 및 VARCHAR 열에서 매우 효과적입니다. 특히 제품 설명, 사용자 의견 또는 JSON 문자열과 같은 자유 형식 텍스트에 적합합니다.

Mostly

Mostly 인코딩은 열의 데이터 형식이 대부분 저장되는 값에 필요한 데이터 형식보다 큰 경우에 유용합니다. 이러한 열 형식에 Mostly 인코딩을 지정하면 열에 저장되어 있는 대부분 값을 더 작은 표준 스토리지 크기로 압축할 수 있습니다. 압축되지 않는 나머지 값들은 원시 형태로 저장됩니다. 예를 들어 INT2 열 같은 16비트 열을 8비트 스토리지로 압축할 수 있습니다.

일반적으로 Mostly 인코딩은 다음과 같은 데이터 형식에서 유효합니다.

  • SMALLINT/INT2(16비트)

  • INTEGER/INT(32비트)

  • BIGINT/INT8(64비트)

  • DECIMAL/NUMERIC(64비트)

열의 데이터 형식 크기에 따라 적합한 유형의 Mostly 인코딩을 선택합니다. 예를 들어 16비트 정수 열로 정의되어 있는 열에는 MOSTLY8을 적용합니다. 16비트 데이터 형식의 열에 MOSTLY16을 적용하거나, 혹은 32비트 데이터 형식의 열에 MOSTLY32를 적용하는 것은 허용되지 않습니다.

열에서 압축할 수 없는 값이 비교적 많은 경우에는 인코딩이 압축하지 않는 것보다 대부분 효과적이지 못할 수도 있습니다. 이러한 인코딩 중 하나를 열에 적용하기 전에 확인합니다. 로드하려고 하는(혹은 앞으로 로드할 가능성이 있는) 대부분 값이 다음 표의 범위에 해당해야 합니다.

인코딩 압축된 스토리지 크기 압축할 수 있는 값의 범위(범위를 벗어나는 값은 원시 형태로 저장됨)
MOSTLY8 1바이트(8비트) -128~127
LZO 2바이트(16비트) -32768~32767
MOSTLY32 4바이트(32비트) 4 bytes
참고

소수 값인 경우에는 값이 범위에 해당하는지 확인할 때 소수점을 무시하십시오. 예를 들어 1,234.56은 123,456으로 처리되어 MOSTLY32 열에서 압축될 수 있습니다.

예를 들어 VENUE 테이블의 VENUEID 열은 원시 형태의 정수 열로 정의됩니다. 이 말은 열의 값이 4바이트의 스토리지를 소비한다는 것을 의미합니다. 하지만 현재 열 값의 범위는 0~309입니다. 따라서 이 테이블을 재생성한 후 VENUEID 열에 MOSTLY16 인코딩을 적용하여 다시 로드하면 해당 열 값의 스토리지가 2바이트로 줄어듭니다.

다른 테이블에서 참조한 VENUEID 값의 범위가 대부분 0~127이었다면 외래 키 열을 MOSTLY8로 인코딩하는 것이 좋을 수도 있습니다. 따라서 선택을 하기 전에 참조 테이블 데이터를 대상으로 여러 쿼리를 실행하여 값이 해당하는 범위가 8비트인지, 16비트인지 또는 32비트인지 확인해야 합니다.

다음 표는 MOSTLY8, MOSTLY16 및 MOSTLY32 인코딩을 사용할 때 특정 숫자 값의 압축 크기를 나타낸 것입니다.

원래 값 원래 INT 또는 BIGINT 크기(바이트) MOSTLY8 압축 크기(바이트) MOSTLY16 압축 크기(바이트) MOSTLY32 압축 크기(바이트)
1 4 1 2 4
10 4 1 2 4
100 4 1 2 4
1000 4 원시 데이터 크기와 동일함 2 4
10000 4 2 4
20000 4 2 4
40000 8 원시 데이터 크기와 동일함 4
100000 8 4
2000000000 8 4
Run length

Run length 인코딩은 연속해서 반복되는 값을 해당 값과 연속해서 발생하는 횟수(실행 길이)로 구성된 토큰으로 대체합니다. 디스크에 저장되어 있는 열 값 블록마다 고유 값의 딕셔너리가 별도로 생성됩니다. Amazon Redshift 디스크 블록은 1MB를 차지합니다. 이 인코딩은 예를 들어 테이블이 데이터 값을 기준으로 정렬되는 경우처럼 데이터 값이 종종 연속해서 반복되는 테이블에 가장 적합합니다.

예를 들어 큰 차원 테이블의 열에 가능한 값이 10개 미만인 COLOR 열과 같이 예상대로 작은 도메인이 있다고 가정합니다. 이러한 값은 데이터가 정렬되지 않은 경우에도 테이블 전체에서 긴 순서로 나타날 수 있습니다.

정렬 키로 지정하는 열에 run length 인코딩을 적용하는 것은 바람직하지 않습니다. 블록에 비슷한 수의 행이 저장되는 경우에는 범위를 제한한 스캔이 훨씬 효과적입니다. 하지만 동일한 쿼리에서 정렬 키 열이 다른 열보다 훨씬 높게 압축되는 경우에는 범위를 제한한 스캔 효과가 떨어질 수도 있습니다.

다음 표는 COLOR 열을 예로 들어 run length 인코딩의 적용 방식을 나타낸 것입니다.

원래 데이터 값 원래 크기(바이트) 압축된 값(토큰) 압축된 크기(바이트)
Blue 4 4 5
Blue 4 0
Green 5 5 6
Green 5 0
Green 5 0
Blue 4 {1,Blue} 5
Yellow 6 {4,Yellow} 7
Yellow 6 0
Yellow 6 0
Yellow 6 0
합계 51 23
Text255 and Text32k

Text255 및 Text32k 인코딩은 동일한 단어가 자주 반복되는 VARCHAR 열을 압축하는 데 유용합니다. 디스크에 저장되어 있는 열 값 블록마다 고유 단어의 딕셔너리가 별도로 생성됩니다. Amazon Redshift 디스크 블록은 1MB를 차지합니다. 딕셔너리에는 열에서 첫 고유 단어 245개가 저장됩니다. 이러한 단어들은 디스크에서 245개 값 중 하나를 표현하는 1바이트 인덱스 값으로 대체되고, 딕셔너리에 표현되지 않는 단어들은 모두 비압축 상태로 저장됩니다. 이 프로세스가 1MB 디스크 블록마다 반복됩니다. 인덱스로 대체된 단어가 열에 자주 나타나면 열의 압축비가 높아집니다.

Text32k 인코딩일 때도 원칙은 동일하지만 각 블록의 딕셔너리가 특정 수의 단어를 수집하지는 않습니다. 대신에 딕셔너리가 전체 입력 항목이 일부 오버헤드를 제외하고 32K에 도달할 때까지 발견하는 고유 단어를 각각 인덱싱합니다. 인덱스 값은 2개 바이트로 저장됩니다.

예를 들어 VENUE 테이블의 VENUENAME 열을 가정하겠습니다. 이 열에서 Arena, Center, Theatre 같은 단어들이 반복되어 text255 압축을 적용한다면 이러한 단어들이 각 블록에서 발견되는 첫 245개 단어에 포함될 가능성이 높습니다. 그렇다면 이 열에는 압축이 유리합니다. 이러한 단어들이 나올 때마다 스토리지를 1바이트(그렇지 않을 경우 각각 5, 6 또는 7바이트)만 차지하기 때문입니다.

ZSTD

ZSTD(Zstandard) 인코딩은 다양한 데이터 세트에서도 높은 압축비로 우수한 성능을 제공합니다. 제품 설명, 사용자 주석, 로그, JSON 문자열처럼 길고 짧은 문자열이 다양하게 저장되는 CHAR 및 VARCHAR 열에서 특히 효과적입니다. Delta 인코딩 또는 Mostly 인코딩 등 일부 알고리즘이 압축하지 않는 것보다 더 많은 스토리지 공간을 사용할 가능성이 있는 경우에도 ZSTD에서의 디스크 사용량이 늘어날 가능성이 높지 않습니다.

ZSTD는 SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP 및 TIMESTAMPTZ 데이터 형식을 지원합니다.

다음 표는 지원되는 압축 인코딩과 인코딩을 지원하는 데이터 형식을 구분한 것입니다.

인코딩 유형 CREATE TABLE 및 ALTER TABLE 문의 키워드 데이터 타입
Raw(압축 없음) RAW 모두
AZ64 AZ64 SMALLINT, INTEGER, BIGINT, DECIMAL, DATE, TIMESTAMP, TIMESTAMPTZ
Byte dictionary BYTEDICT SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ
델타

델타

델타

SMALLINT, INT, BIGINT, DATE, TIMESTAMP, DECIMAL

INT, BIGINT, DATE, TIMESTAMP, DECIMAL

LZO LZO SMALLINT, INTEGER, BIGINT, DECIMAL, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ, SUPER
Mostlyn

LZO

LZO

LZO

SMALLINT, INT, BIGINT, DECIMAL

INT, BIGINT, DECIMAL

BIGINT, DECIMAL

Run-length RUNLENGTH SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ
텍스트

TEXT255

TEXT32K

VARCHAR

VARCHAR

Zstandard ZSTD SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ, SUPER