카디널리티 순으로 정렬(낮은 것부터 높은 것까지)
시간 세분화 수준은 중요합니다
timestamp를 사용할 때는 카디널리티와 정밀도 사이의 절충 관계를 고려해야 합니다. 마이크로초 정밀도의 timestamp는 매우 높은 카디널리티를 형성하므로(거의 각 행마다 고유한 값이 1개씩 존재) ClickHouse의 희소 프라이머리 인덱스 효율이 떨어집니다. 반면 반올림된 timestamp는 카디널리티가 더 낮아 인덱스 스키핑이 더 효과적으로 동작하지만, 시간 기반 쿼리의 정밀도는 낮아집니다.
runnable editable
평균이 아닌 개별 쿼리에 집중하십시오
메모리와 행 스캔
GROUP BY user_id, error_message, url_path와 같은 쿼리는 세 값의 고유한 조합마다 별도의 메모리 상태를 생성합니다. 사용자 수, 오류 유형, URL 경로가 늘어나면 메모리에 동시에 유지해야 하는 집계 상태가 쉽게 수백만 개까지 늘어날 수 있습니다.
극단적인 경우 Sentry는 결정적 샘플링을 사용합니다. 10% 샘플링은 대부분의 집계에서 약 5% 수준의 정확도를 유지하면서 메모리 사용량을 90% 줄여 줍니다:
cityHash64()가 동일한 입력에 대해 항상 같은 hash 값을 생성한다는 점입니다. 따라서 user_id = 12345는 언제나 동일한 값으로 hash되며, 그 결과 해당 사용자는 10% 샘플(sample)에 항상 포함되거나 전혀 포함되지 않습니다. 즉, 쿼리마다 나타났다 사라지는 현상이 발생하지 않습니다.
Sentry의 비트 마스크 최적화
영상 자료
- Lost in the Haystack - 높은 카디널리티 집계 최적화 - Sentry의 프로덕션 경험을 바탕으로 한 메모리 최적화 교훈
- ClickHouse 성능 분석 - Alexey Milovidov가 설명하는 디버깅 방법론
- ClickHouse Meetup: 쿼리 최적화 기법 - 커뮤니티의 최적화 전략