메인 콘텐츠로 건너뛰기

쿼리의 메모리 한도 초과

처음 ClickHouse를 사용하면 ClickHouse가 마치 마법처럼 느껴질 때가 많습니다. 가장 큰 데이터셋과 가장 복잡한 쿼리에서도 모든 쿼리가 매우 빠르게 실행되기 때문입니다. 하지만 실제 환경에서는 결국 ClickHouse의 한계도 시험받게 됩니다. 메모리 한도를 초과하는 쿼리는 여러 가지 원인으로 발생할 수 있습니다. 가장 흔한 원인은 카디널리티가 높은 필드에서 대규모 조인이나 집계를 수행하는 경우입니다. 성능이 매우 중요하고 이러한 쿼리가 꼭 필요하다면, 일반적으로는 단순히 리소스를 확장하는 방법을 권장합니다. ClickHouse Cloud는 쿼리 응답성을 유지할 수 있도록 이를 자동으로, 그리고 손쉽게 처리합니다. 다만 자가 관리형 환경에서는 이것이 항상 간단하지 않을 수 있고, 최적의 성능 자체가 꼭 필요한 것은 아닐 수도 있다는 점도 잘 알고 있습니다. 이런 경우에는 몇 가지 선택지가 있습니다.

집계

메모리 사용량이 큰 집계 또는 정렬 시나리오에서는 max_bytes_before_external_group_bymax_bytes_before_external_sort 설정을 각각 사용할 수 있습니다. 전자에 대해서는 여기에서 자세히 설명합니다. 요약하면, 이 설정은 메모리 임계값을 초과할 경우 집계 작업 결과를 디스크로 spill할 수 있도록 합니다. 이로 인해 쿼리 성능은 불가피하게 저하되지만, 쿼리에서 OOM이 발생하지 않도록 하는 데 도움이 됩니다. 후자의 정렬 설정은 메모리 사용량이 큰 정렬에서 발생하는 유사한 문제를 해결하는 데 도움이 됩니다. 이는 특히 조정 노드가 하위 세그먼트로부터 정렬된 응답을 받는 분산 환경에서 중요할 수 있습니다. 이 경우 조정 서버는 사용 가능한 메모리보다 더 큰 데이터셋을 정렬해야 할 수 있습니다. max_bytes_before_external_sort를 사용하면, 정렬 작업도 디스크로 spill되도록 허용할 수 있습니다. 이 설정은 또한 사용자가 GROUP BY 뒤에 LIMIT가 있는 ORDER BY를 사용하는 경우에도 유용하며, 특히 쿼리가 분산되는 경우 더욱 그렇습니다.

조인

조인에서는 필요한 메모리를 줄이는 데 도움이 되도록 여러 JOIN 알고리즘을 선택할 수 있습니다. 기본적으로는 해시 조인이 사용되며, 기능 지원 측면에서 가장 완전하고 대체로 성능도 가장 우수합니다. 이 알고리즘은 JOIN의 오른쪽 테이블을 메모리 내 해시 테이블에 로드한 뒤, 이를 기준으로 왼쪽 테이블을 평가합니다. 따라서 메모리 사용을 최소화하려면 더 작은 테이블을 오른쪽에 배치해야 합니다. 다만 이 방식도 메모리 제약이 있는 경우에는 한계가 있습니다. 이런 경우에는 join_algorithm 설정을 통해 partial_merge 조인을 활성화할 수 있습니다. sort-merge 알고리즘의 파생형인 이 방식은 먼저 오른쪽 테이블을 블록으로 정렬하고 각 블록에 대해 MinMax 인덱스를 생성합니다. 그런 다음 왼쪽 테이블의 일부를 조인 키 기준으로 정렬한 후 오른쪽 테이블과 조인합니다. MinMax 인덱스는 필요하지 않은 오른쪽 테이블 블록을 건너뛰는 데 사용됩니다. 이 방식은 성능 저하를 감수하는 대신 메모리 사용량을 줄일 수 있습니다. 이 개념을 더 확장한 full_sorting_merge 알고리즘은 오른쪽이 매우 크고 메모리에 들어가지 않으며 lookup이 불가능한 경우(예: 복잡한 서브쿼리)에도 JOIN을 수행할 수 있게 합니다. 이 경우 오른쪽과 왼쪽 모두 메모리에 맞지 않으면 디스크에서 정렬되므로, 큰 테이블도 조인할 수 있습니다. 20.3부터 ClickHouse는 join_algorithm 설정에서 auto 값을 지원합니다. 이 값은 ClickHouse가 적응형 조인 방식을 적용하도록 하며, 메모리 제한에 도달하기 전까지는 해시 조인 알고리즘을 우선 사용하고, 그 시점에 partial_merge 알고리즘을 시도합니다. 마지막으로 조인과 관련해, 분산 조인의 동작 방식과 메모리 활용을 최소화하는 방법도 함께 숙지하는 것이 좋습니다. 자세한 내용은 여기에서 확인할 수 있습니다.
마지막 수정일 2026년 6월 10일