> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 쿼리의 메모리 한도 초과

> 쿼리의 메모리 한도 초과 오류 해결

export const Image = ({img, alt, size}) => {
  return <Frame>
      <img src={img} alt={alt} />
    </Frame>;
};

<div id="troubleshooting-out-of-memory-issues">
  ## 쿼리의 메모리 한도 초과
</div>

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

<div id="aggregations">
  ### 집계
</div>

메모리 사용량이 큰 집계 또는 정렬 시나리오에서는
[`max_bytes_before_external_group_by`](/ko/reference/settings/session-settings#max_bytes_before_external_group_by)
및 [`max_bytes_before_external_sort`](/ko/reference/settings/session-settings#max_bytes_ratio_before_external_sort) 설정을 각각 사용할 수 있습니다.
전자에 대해서는 [여기](/ko/reference/statements/select/group-by#group-by-in-external-memory)에서 자세히 설명합니다.

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

<div id="joins">
  ### 조인
</div>

조인에서는 필요한 메모리를 줄이는 데 도움이 되도록 여러 `JOIN` 알고리즘을 선택할 수 있습니다. 기본적으로는 해시 조인이 사용되며, 기능 지원 측면에서 가장 완전하고 대체로 성능도 가장 우수합니다.
이 알고리즘은 `JOIN`의 오른쪽 테이블을 메모리 내 해시
테이블에 로드한 뒤, 이를 기준으로 왼쪽 테이블을 평가합니다. 따라서 메모리 사용을 최소화하려면
더 작은 테이블을 오른쪽에 배치해야 합니다. 다만 이 방식도
메모리 제약이 있는 경우에는 한계가 있습니다. 이런 경우에는 [`join_algorithm`](/ko/reference/settings/session-settings#join_algorithm)
설정을 통해 `partial_merge` 조인을 활성화할 수 있습니다. [sort-merge 알고리즘](https://en.wikipedia.org/wiki/Sort-merge_join)의
파생형인 이 방식은 먼저 오른쪽 테이블을 블록으로 정렬하고 각 블록에 대해 MinMax 인덱스를 생성합니다.
그런 다음 왼쪽 테이블의 일부를 조인 키 기준으로 정렬한 후 오른쪽
테이블과 조인합니다. MinMax 인덱스는 필요하지 않은 오른쪽 테이블 블록을 건너뛰는 데 사용됩니다.
이 방식은 성능 저하를 감수하는 대신 메모리 사용량을 줄일 수 있습니다. 이 개념을
더 확장한 `full_sorting_merge` 알고리즘은 오른쪽이 매우 크고
메모리에 들어가지 않으며 lookup이 불가능한 경우(예: 복잡한 서브쿼리)에도 `JOIN`을 수행할 수 있게 합니다. 이 경우 오른쪽과 왼쪽 모두
메모리에 맞지 않으면 디스크에서 정렬되므로, 큰 테이블도
조인할 수 있습니다.

<Image img="https://mintcdn.com/private-7c7dfe99-fix-nav-issues/ldyQZWT-cIRJh7wo/images/knowledgebase/memory-limit-exceeded-for-query.png?fit=max&auto=format&n=ldyQZWT-cIRJh7wo&q=85&s=0701a7248c85072732f2d5707977d150" size="md" alt="Joins algorithms" width="1024" height="768" data-path="images/knowledgebase/memory-limit-exceeded-for-query.png" />

20.3부터 ClickHouse는 `join_algorithm` 설정에서 auto 값을 지원합니다.
이 값은 ClickHouse가 적응형 조인 방식을 적용하도록 하며, 메모리 제한에 도달하기 전까지는 해시 조인
알고리즘을 우선 사용하고, 그 시점에
partial\_merge 알고리즘을 시도합니다. 마지막으로 조인과 관련해, 분산 조인의 동작 방식과
메모리 활용을 최소화하는 방법도 함께 숙지하는 것이 좋습니다. 자세한 내용은 [여기](/ko/reference/statements/in#distributed-subqueries)에서 확인할 수 있습니다.
