CREATE TABLE ... CODEC
CREATE TABLE ... CODEC
기본적으로 ClickHouse는 자체 관리 버전에서 lz4 압축을, ClickHouse Cloud에서는 zstd를 적용합니다.
MergeTree 계열 엔진의 경우 서버 구성의 compression 섹션에서 기본 압축 방법을 변경할 수 있습니다.
CREATE TABLE 쿼리에서 각 개별 컬럼의 압축 방법을 정의할 수도 있습니다.
CREATE TABLE codec_example
(
dt Date CODEC(ZSTD),
ts DateTime CODEC(LZ4HC),
float_value Float32 CODEC(NONE),
double_value Float64 CODEC(LZ4HC(9)),
value Float32 CODEC(Delta, ZSTD)
)
ENGINE = <Engine>
...
Default codec을 지정해 런타임에 다른 설정(및 데이터 속성)에 의존할 수 있는 기본 압축을 참조할 수 있습니다.
예: value UInt64 CODEC(Default) — codec 지정이 없는 것과 같습니다.
Adaptive Codec Selection도 참고하세요.
또한 컬럼에서 현재 CODEC을 제거하고 config.xml의 기본 압축을 사용할 수 있습니다:
ALTER TABLE codec_example MODIFY COLUMN float_value CODEC(Default);
Codec은 파이프라인으로 결합할 수 있습니다, 예: CODEC(Delta, Default).
lz4 같은 외부 유틸리티로 ClickHouse 데이터베이스 파일을 압축 해제할 수 없습니다. 대신 특수한 clickhouse-compressor 유틸리티를 사용하세요.
압축은 다음 테이블 엔진에서 지원됩니다:
- MergeTree 계열. 컬럼 압축 codec과 compression 설정으로 기본 압축 방법 선택을 지원합니다.
- Log 계열. 기본적으로
lz4압축 방법을 사용하며 컬럼 압축 codec을 지원합니다. - Set. 기본 압축만 지원합니다.
- Join. 기본 압축만 지원합니다.
ClickHouse는 범용 codec과 특수 codec을 지원합니다.
General Purpose Codecs
NONE
NONE — 압축 없음.
LZ4
LZ4 — 기본으로 사용되는 무손실 data compression algorithm. LZ4 고속 압축을 적용합니다.
LZ4HC
LZ4HC[(level)] — 설정 가능한 level의 LZ4 HC(high compression) 알고리즘. 기본 level: 9. level <= 0 설정은 기본 level을 적용합니다. 가능한 level: [1, 12]. 권장 level 범위: [4, 9].
ZSTD
ZSTD[(level)] — 설정 가능한 level의 ZSTD compression algorithm. 가능한 level: [1, 22]. 기본 level: 1.
높은 압축 level은 한 번 압축하고 반복적으로 압축 해제하는 비대칭 시나리오에 유용합니다. level이 높을수록 더 나은 압축과 더 높은 CPU 사용을 의미합니다.
ZXC
ZXC[(level)] — 설정 가능한 level의 비대칭 zxc compression algorithm. 가능한 level: [1, 7]. 기본 level: 3.
ZXC는 매우 빠른 압축 해제를 위해 느린 압축을 맞바꾸며, LZ4와 ZSTD 사이의 압축 비율을 가집니다. 한 번 압축하고 여러 번 압축 해제하는 패턴에 잘 맞으며, 현대 ARM 코어에서 가장 빠르게 압축 해제됩니다. level이 높을수록 더 나은 압축과 더 느린 압축을 의미하며, 압축 해제는 빠르게 유지됩니다.
이 codec은 실험적이며 사용하려면 SET enable_zxc_codec = 1이 필요합니다.
Obsolete: ZSTD_QAT
Obsolete: DEFLATE_QPL
Specialized Codecs
이 codec들은 데이터의 특정 특징을 활용해 압축을 더 효과적으로 만들기 위해 설계되었습니다. 이 codec들 중 일부는 데이터 자체를 압축하지 않고, 대신 범용 codec을 사용하는 두 번째 압축 단계가 더 높은 데이터 압축률을 달성할 수 있도록 데이터를 전처리합니다.
Delta
Delta(delta_bytes) — 첫 번째 값을 제외하고 원시 값을 인접한 두 값의 차이로 대체하는 압축 접근 방식입니다. delta_bytes는 원시 값의 최대 크기이며, 기본값은 sizeof(type)입니다. 인자로 delta_bytes를 지정하는 것은 더 이상 사용되지 않으며(now deprecated) 향후 릴리스에서 지원이 제거될 것입니다. Delta는 데이터 준비 codec입니다, 즉 단독으로 사용할 수 없습니다.
DoubleDelta
DoubleDelta(bytes_size) — 델타의 델타를 계산하고 압축된 이진 형식으로 씁니다. bytes_size는 Delta codec의 delta_bytes와 유사한 의미를 가집니다. 인자로 bytes_size를 지정하는 것은 더 이상 사용되지 않으며(now deprecated) 향후 릴리스에서 지원이 제거될 것입니다. 시계열 데이터처럼 일정한 간격(stable stride)을 가진 단조 증가 시퀀스에 대해 최적의 압축률이 달성됩니다. 모든 숫자 타입과 함께 사용할 수 있습니다. Gorilla TSDB에서 사용된 알고리즘을 구현하고 64비트 타입을 지원하도록 확장합니다. 32비트 델타에 1개의 추가 비트를 사용합니다: 4비트 접두사 대신 5비트 접두사. 추가 정보는 Gorilla: A Fast, Scalable, In-Memory Time Series Database의 Compressing Time Stamps를 참고하세요. DoubleDelta는 데이터 준비 codec입니다, 즉 단독으로 사용할 수 없습니다.
GCD
GCD() - - 컬럼 값의 최대 공약수(GCD)를 계산한 다음 각 값을 GCD로 나눕니다. 정수, 십진수, 날짜/시간 컬럼과 함께 사용할 수 있습니다. 이 codec은 값이 GCD의 배수로 변경(증가 또는 감소)하는 컬럼에 잘 맞습니다, 예: 24, 28, 16, 24, 8, 24 (GCD = 4). GCD는 데이터 준비 codec입니다, 즉 단독으로 사용할 수 없습니다.
Gorilla
Gorilla(bytes_size) — 현재와 이전 부동 소수점 값 사이의 XOR을 계산하고 압축된 이진 형식으로 씁니다. 연속 값 사이의 차이가 작을수록, 즉 시리즈 값의 변화가 느릴수록 압축률이 더 좋습니다. Gorilla TSDB에서 사용된 알고리즘을 구현하고 64비트 타입을 지원하도록 확장합니다. 가능한 bytes_size 값: 1, 2, 4, 8, 기본값은 1, 2, 4, 8 중 하나와 같으면 sizeof(type)입니다. 그 외의 모든 경우에는 1입니다. 추가 정보는 Gorilla: A Fast, Scalable, In-Memory Time Series Database의 섹션 4.1을 참고하세요.
ALP
ALP(variant) — 부동 소수점 데이터를 위한 적응형 무손실 압축. Float32와 Float64를 지원합니다. 자세한 내용은 ALP: Adaptive lossless floating-point compression을 참고하세요.
codec은 선택적 variant 인자를 허용합니다:
ALP()또는ALP(AUTO)(기본값) — STD를 사용하고 추정된 압축 크기에 따라 RD로 폴백합니다.ALP(STD)— 표준 ALP variant. 각 값을 십진 거듭제곱을 사용해 정확한 스케일된 정수로 표현한 다음, 결과 정수를 Frame-of-Reference와 bit-packing으로 압축합니다. 표현할 수 없는 값은 원시 예외로 저장됩니다. 십진수에서 유래한 숫자(예: 측정, 가격)에 가장 잘 작동합니다.ALP(RD)— Real Doubles variant. 각 값의 비트 패턴을 재해석하고 높은 부분(부호 + 지수 + 상위 가수 비트)과 낮은 부분으로 분할합니다. 높은 부분은 사전 인코딩되고(최대 8개 항목), 낮은 부분은 bit-packed됩니다. 많은 값이 같은 높은 비트를 공유할 때 가장 잘 작동합니다.
이 codec은 베타이며 사용하려면 SET enable_alp_codec = 1이 필요합니다.
FPC
FPC(level, float_size) - 두 개의 예측기 중 더 나은 것을 사용해 시퀀스의 다음 부동 소수점 값을 반복적으로 예측한 다음, 실제 값과 예측 값을 XOR하고 결과를 leading-zero 압축합니다. Gorilla와 유사하게, 느리게 변하는 부동 소수점 값 시리즈를 저장할 때 효율적입니다. 64비트 값(double)의 경우 FPC는 Gorilla보다 빠르며, 32비트 값의 경우 결과가 다를 수 있습니다. 가능한 level 값: 1-28, 기본값은 12입니다. 가능한 float_size 값: 4, 8, 타입이 Float이면 기본값은 sizeof(type)입니다. 그 외의 모든 경우에는 4입니다. 알고리즘의 자세한 설명은 High Throughput Compression of Double-Precision Floating-Point Data를 참고하세요.
SZ3
SZ3 또는 SZ3(algorithm, error_bound_mode, error_bound) - Float32, Float64, Array(Float32), Array(Float64) 타입의 컬럼을 위한 손실이 있지만 오류 경계가 있는 codec(SZ3 Lossy Compressor)입니다. 배열 컬럼의 경우 모든 배열이 같은 길이를 가질 때 압축이 가장 효과적입니다(그러면 고정 폭 벡터로 압축됩니다); 다른 길이의 배열도 여전히 지원되며 값의 평면 시퀀스로 압축됩니다. 이 codec은 Map 컬럼에는 적용할 수 없습니다. 손실 압축으로 키가 손상될 수 있기 때문입니다. 'algorithm'에 지원되는 값은 ALGO_LORENZO_REG, ALGO_INTERP_LORENZO, ALGO_INTERP입니다. 'error_bound_mode'에 지원되는 값은 ABS, REL, PSNR, ABS_AND_REL입니다. 인자 'error_bound'는 최대 오류이며 Float64 타입입니다.
이 codec은 실험적이며 사용하려면 SET enable_sz3_codec = 1이 필요합니다.
T64
T64 — 정수 데이터 타입(Enum, Date, DateTime 포함)의 값에서 사용하지 않는 높은 비트를 잘라내는 압축 접근 방식입니다. 알고리즘의 각 단계에서 codec은 64개 값을 블록으로 가져와 64x64 비트 행렬에 넣고, 전치한 다음 사용하지 않는 값 비트를 잘라내고 나머지를 시퀀스로 반환합니다. 사용하지 않는 비트는 압축이 사용되는 전체 데이터 파트의 최대값과 최소값 사이에서 다르지 않은 비트입니다.
DoubleDelta와 Gorilla codec은 Gorilla TSDB에서 압축 알고리즘의 구성 요소로 사용됩니다. Gorilla 접근 방식은 타임스탬프와 함께 느리게 변하는 값 시퀀스가 있는 시나리오에서 효과적입니다. 타임스탬프는 DoubleDelta codec으로 효과적으로 압축되고, 값은 Gorilla codec으로 효과적으로 압축됩니다. 예를 들어 효과적으로 저장된 테이블을 얻으려면 다음 구성으로 만들 수 있습니다:
CREATE TABLE codec_example
(
timestamp DateTime CODEC(DoubleDelta),
slow_values Float32 CODEC(Gorilla)
)
ENGINE = MergeTree()
Quantized
Quantized(method, dimensions[, ...]) — Array(Float32), Array(Float64) 또는 Array(BFloat16) 타입의 컬럼에 대한 근사 벡터 검색을 지원하는 특수 codec입니다.
원본의 전체 정밀도 벡터와 함께 각 벡터에 대한 압축된 양자화 코드를 저장합니다.
MergeTree 계열 테이블에서 vector_search_use_quantized_codes 설정이 있는 벡터 검색 쿼리는 양자화 코드를 스캔해 후보 목록(shortlist)을 만들고, 이후 전체 정밀도 벡터에 대한 결과를 다시 점수화합니다.
이 2단계 검색은 일반 전체 정밀도 스캔보다 적은 바이트를 읽는 대신 더 낮은 재현율(recall)을 대가로 합니다.
dimensions는 벡터 길이입니다; 지원되는 method 값은 rabitq, turboquant, int8, prefix, product이며, 각각 다른 크기/정확도/거리 함수 절충입니다.
codec은 CREATE TABLE에서만 설정할 수 있으며, ALTER TABLE로는 추가, 제거 또는 변경할 수 없습니다(ADD COLUMN ... CODEC(Quantized(...)) 포함).
다른 codec과 체인할 수 없습니다(암호화 codec AES_128_GCM_SIV조차도).
자세한 내용은 Vector search with quantized codecs를 참고하세요.
이 codec은 실험적이며 사용하려면 SET enable_quantized_codec = 1이 필요합니다.
SET enable_quantized_codec = 1;
CREATE TABLE vectors
(
id UInt32,
vec Array(BFloat16) CODEC(Quantized('rabitq', 1536))
)
ENGINE = MergeTree ORDER BY id;
Encryption Codecs
이 codec들은 실제로 데이터를 압축하지 않고 디스크의 데이터를 암호화합니다. encryption 설정으로 암호화 키가 지정된 경우에만 사용할 수 있습니다. 암호화된 데이터는 보통 어떤 의미 있는 방식으로도 압축될 수 없기 때문에 암호화는 codec 파이프라인 끝에서만 의미가 있습니다.
Encryption codecs:
AES_128_GCM_SIV
CODEC('AES-128-GCM-SIV') — RFC 8452 GCM-SIV 모드에서 AES-128로 데이터를 암호화합니다.
AES-256-GCM-SIV
CODEC('AES-256-GCM-SIV') — GCM-SIV 모드에서 AES-256으로 데이터를 암호화합니다.
이 codec들은 고정 nonce를 사용하므로 암호화는 결정적입니다. 이는 ReplicatedMergeTree 같은 중복 제거 엔진과 호환되게 하지만 약점이 있습니다: 같은 데이터 블록이 두 번 암호화되면 결과 ciphertext가 정확히 같아지므로, 디스크를 읽을 수 있는 공격자가 이 동등성을 볼 수 있습니다(내용은 얻지 못하더라도 동등성만).
"*MergeTree" 계열을 포함한 대부분의 엔진은 codec을 적용하지 않고 인덱스 파일을 디스크에 만듭니다. 즉 암호화된 컬럼이 인덱싱되면 평문이 디스크에 나타날 수 있습니다.
암호화된 컬럼에서 특정 값(WHERE 절 등)을 언급하는 SELECT 쿼리를 수행하면 그 값이 system.query_log에 나타날 수 있습니다. 로깅을 비활성화하고 싶을 수 있습니다.
Example
CREATE TABLE mytable
(
x String CODEC(AES_128_GCM_SIV)
)
ENGINE = MergeTree ORDER BY x;
압축을 적용해야 하면 명시적으로 지정해야 합니다. 그렇지 않으면 데이터에 암호화만 적용됩니다.
Example
CREATE TABLE mytable
(
x String CODEC(Delta, LZ4, AES_128_GCM_SIV)
)
ENGINE = MergeTree ORDER BY x;
Adaptive Codec Selection
위의 특수 codec들은 적절한 데이터를 극적으로 줄일 수 있지만, 선택에는 전문성이 필요하고 데이터가 시간에 따라 변하는 컬럼에 단일 선택이 맞지 않습니다. enable_adaptive_codec_selection MergeTree 설정을 활성화하면 ClickHouse가 선택해 줍니다. 기본 codec(CODEC(Default) 또는 CODEC 없음)을 사용하는 컬럼에 대해, 각 블록은 테이블의 기본 codec, NONE, 그리고 컬럼 타입에 맞는 특수 codec 중 어느 것이 가장 작게 압축하든 그 codec으로 기록됩니다.
특수 codec은 현재 최대 64비트 정수, enum, 날짜와 시간, Decimal32/Decimal64, IPv4, Float32/Float64에 대해 선택됩니다. 다른 컬럼은 값에 대해 기본 codec과 NONE 사이에서 선택합니다.
블록은 기본 codec이 만드는 것보다 결코 크지 않으며, 압축할 수 없는 데이터는 원시로 저장됩니다(압축하면 약간 더 큰 파일이 만들어지고 읽기가 더 느려집니다). 작업은 배경에서, 병합과 mutation에서 수행되며, 여기서 데이터는 어차피 재압축됩니다. 삽입 속도는 영향을 받지 않습니다. 쿼리는 종종 더 빨라집니다: 디스크에서 가져오는 데이터가 적고, 쿼리가 읽는 모든 블록은 먼저 압축을 풀어야 하며, 특수 codec은 기본 LZ4보다 더 빨리 압축을 풉니다. 각 블록은 기록된 codec을 기록하므로 읽기에 설정이 필요하지 않으며, 모든 데이터가 읽을 수 있는 상태로 기능은 언제든 끌 수 있습니다.
CREATE TABLE adaptive
(
time DateTime,
user_id UInt64
)
ENGINE = MergeTree
ORDER BY time
SETTINGS enable_adaptive_codec_selection = 1;
INSERT INTO adaptive SELECT toDateTime('2026-01-01') + number, cityHash64(number) FROM numbers(1000000);
OPTIMIZE TABLE adaptive FINAL;
mergeTreeCodecBlockCounts 테이블 함수로 어떻게 동작하는지 관찰할 수 있습니다. 여기서 time은 꾸준히 증가하므로 블록 내에서 변하는 비트만 저장하는 T64가 모든 블록에서 기본 codec을 이겼습니다. user_id는 어떤 codec도 줄일 수 없는 해시를 보유하므로 그 블록은 원시로 저장되었습니다:
SELECT column, codec_block_counts FROM mergeTreeCodecBlockCounts(currentDatabase(), 'adaptive');
┌─column──┬─codec_block_counts─┐
1. │ time │ {'T64':62} │
2. │ user_id │ {'NONE':123} │
└─────────┴────────────────────┘
Related content
- Blog: Optimizing ClickHouse with Schemas and Codecs
- Blog: Working with time series data in ClickHouse