딕셔너리 모범 사례
딕셔너리 모범 사례 (Dictionary best practices)
이 페이지는 올바른 딕셔너리 레이아웃을 고르는 방법, 딕셔너리가 JOIN보다 더 나은 경우(그리고 그렇지 않은 경우), 그리고 딕셔너리 사용량을 모니터링하는 방법에 대한 실용적인 지침을 다뤄요.
출처: 문서
본문
이 페이지는 올바른 딕셔너리 레이아웃을 고르는 법, 딕셔너리가 JOIN보다 나은 때(그리고 아닐 때), 딕셔너리 사용량 모니터링에 대한 실용적인 지침을 다뤄요.
딕셔너리를 예제와 함께 소개하는 내용은 기본 딕셔너리 가이드를 참고해요.
딕셔너리 vs JOIN 언제 쓸까
딕셔너리는 JOIN의 한쪽이 메모리에 들어맞는 룩업 테이블일 때 가장 잘 동작해요. 표준 JOIN에서 ClickHouse는 오른쪽에서 해시 테이블을 만들고 왼쪽으로 그것을 탐색해요. 나중에 WHERE 필터로 대부분의 행이 버려지더라도 마찬가지예요. 최신 버전(24.12+)은 많은 경우 JOIN 전에 필터를 밀어 넣지만, 항상 그 오버헤드가 사라지는 건 아니에요. 딕셔너리를 쓰면 dictGet을 인라인으로 호출하므로 필터링을 이미 통과한 행에서만 룩업이 일어나요.
하지만 dictGet이 항상 정답은 아니에요. 테이블의 많은 비율의 행에 대해 dictGet을 호출해야 한다면 — 예를 들어 dictGet('dict', 'elevation', id) > 1800 같은 WHERE 조건 — 일반 열+네이티브 인덱스를 쓰는 게 더 나을 수 있어요. ClickHouse는 일반 열에 대해 PREWHERE로 그래뉼(granule)을 건너뛸 수 있지만, dictGet은 인덱스 지원 없이 행마다 평가해요.
대략적인 기준:
- 룩업 키가 이미 준비되어 있는 작은 차원 테이블에 대한 JOIN을 딕셔너리로 대체해요.
- 많은 행에 걸쳐 룩업된 값으로 필터링할 때는 일반 열과 인덱스를 사용해요.
레이아웃 고르기 (Choosing a layout)
LAYOUT 절은 딕셔너리의 내부 데이터 구조를 제어해요. 가능한 모든 레이아웃은 레이아웃 레퍼런스에 문서화되어 있어요.
레이아웃을 고를 때 다음 지침을 참고해요:
flat— 가장 빠른 레이아웃(단순 배열 오프셋 룩업)이지만 키가UInt64여야 하고 기본적으로 500,000개로 제한돼요(max_array_size). 작거나 중간 크기 테이블에서 단조 증가하는 정수 키에 가장 좋아요. 희소한 키 분포(예: 키 값이 1과 500,000)는 배열이 가장 큰 키 크기로 잡히므로 메모리를 낭비해요. 500k 제한에 부딪히면hashed_array로 전환할 신호예요.hashed_array— 대부분의 사용 사례에 권장되는 기본값. 속성을 배열에 저장하고 해시 테이블로 키를 배열 인덱스에 매핑해요.hashed와 거의 비슷하게 빠르지만 특히 속성이 많을 때 메모리 효율이 더 좋아요.hashed— 전체 딕셔너리를 해시 테이블에 저장. 속성이 아주 적을 때hashed_array보다 빠를 수 있지만 속성 수가 늘어나면 메모리를 더 소비해요.complex_key_hashed/complex_key_hashed_array— 키를UInt64로 캐스팅할 수 없을 때(예:String키) 사용해요. 일반(비복합) 레이아웃과 같은 성능 트레이드오프를 따르지만 다릅니다.sparse_hashed—hashed에 비해 CPU를 희생하고 메모리 사용을 줄여요. 대개 최선의 선택은 아니에요. 속성이 하나뿐일 때만 효율적이에요. 대부분의 경우hashed_array가 더 좋아요.cache/ssd_cache— 자주 접근하는 키만 캐시해요. 전체 데이터 세트가 메모리에 안 들어갈 때 유용하지만, 캐시 미스 시 룩업이 소스를 때릴 수 있어요. 지연 시간에 민감한 워크로드에는 권장하지 않아요.direct— 인메모리 저장 없이 모든 룩업에 대해 소스를 조회해요. 데이터가 너무 자주 바뀌어 캐시할 수 없거나 딕셔너리가 메모리에 너무 클 때 사용해요.
딕셔너리 사용량 모니터링 (Monitoring dictionary usage)
system.dictionaries 테이블을 통해 메모리 소비와 상태를 추적해요:
SELECT
name,
status,
element_count,
formatReadableSize(bytes_allocated) AS size,
query_count,
hit_rate,
found_rate,
last_exception
FROM system.dictionaries
주요 열:
bytes_allocated— 딕셔너리가 소비하는 메모리. 딕셔너리는 데이터를 압축하지 않고 저장하므로 압축된 테이블 크기보다 훨씬 클 수 있어요.hit_rate와found_rate—cache레이아웃의 효율성을 평가할 때 유용해요.last_exception— 딕셔너리가 로드되거나 새로고침에 실패할 때 확인해 보세요.