답변:
해시 집계는 단일 (빌드) 입력 만 사용하지만 해시 결합 및 해시 집계 는 내부적으로 동일한 연산자 코드를 사용합니다. 해시 집계 의 기본 작업은 Craig Freedman 이 설명합니다 .
해시 결합과 마찬가지로 해시 집계에는 메모리가 필요합니다. 해시 집계로 쿼리를 실행하기 전에 SQL Server는 카디널리티 추정을 사용하여 쿼리를 실행하는 데 필요한 메모리 양을 추정합니다. 해시 조인을 사용하면 각 빌드 행을 저장하므로 총 메모리 요구 사항은 빌드 행의 수와 크기에 비례합니다. 결합하는 행 수와 결합의 출력 카디널리티는 결합의 메모리 요구 사항에 영향을 미치지 않습니다. 해시 집계를 사용하면 각 그룹마다 하나의 행을 저장하므로 총 메모리 요구 사항은 실제로 출력 그룹 또는 행의 수와 크기에 비례합니다. 열별 그룹의 고유 값이 적고 그룹 수가 적 으면 메모리가 더 적게 필요합니다. 더 많은 그룹 별 그룹 값과 더 많은 그룹이 있으면 더 많은 메모리가 필요합니다.
그는 해시 재귀에 대해 계속 이야기합니다.
메모리가 부족하면 어떻게 되나요? 다시 해시 조인처럼 메모리가 부족하면 tempdb에 행을 흘리기 시작해야합니다. 유출 된 버킷 또는 파티션으로 해시되는 추가 행과 함께 부분적으로 집계 된 결과를 포함하여 하나 이상의 버킷 또는 파티션을 쏟습니다. 유출 된 새 행을 집계하려고 시도하지는 않지만 해시하고 여러 버킷 또는 파티션으로 나눕니다. 모든 입력 그룹 처리를 마치면 완성 된 인 메모리 그룹을 출력하고 유출 된 파티션을 한 번에 하나씩 읽고 집계하여 알고리즘을 반복합니다. 유출 된 행을 여러 파티션으로 나누면 각 파티션의 크기가 줄어들어 알고리즘을 여러 번 반복해야 할 위험이 줄어 듭니다.
해시 구제 금융 은 가볍게 기록되어 있지만 Nacho Alonso Portillo는 구제 금융을 받기 전에 해시 반복기의 최대 재귀 수준은 무엇입니까?
값은 제품에 하드 코딩 된 상수이며 값은 5입니다. 즉, 해시 스캔 연산자가 작업 공간에서 부여 된 메모리에 맞지 않는 주어진 서브 파티션에 대해 정렬 기반 알고리즘에 의존하기 전에 원래 파티션을 더 작은 파티션으로 세분하려는 이전의 5 가지 시도가 발생했음을 의미합니다.
"해시 스캔 연산자"에에 내부 클래스 CQScanHash
에 대한 참조가 있다고 언급 했습니다 sqlmin.dll
. 이 클래스는 실행 계획에서 볼 수있는 해시 연산자 (부분 집계 및 흐름 구분을 포함한 모든 형식)의 구현을 이끌고 있습니다.
이것은 우리를 당신의 질문의 핵심으로 이끌어줍니다-구제 알고리즘은 정확히 무엇을합니까? "정렬 기반"입니까 아니면 "중첩 된 루프의 일종"을 기반으로합니까?
그것은 당신의 관점에 따라 둘 다 틀림 없습니다. 해시 재귀가 수준 5에 도달하면 메모리 내 해시 파티션이 해시 테이블에서 해시 값의 초기 비어있는 b- 트리 인덱스로 변경됩니다. 이전에 유출 된 단일 해시 파티션의 각 행은 b- 트리 인덱스에서 조회되고 적절하게 삽입 (새 그룹)되거나 업데이트 (유지 집계)됩니다.
b- 트리에 대한이 정렬되지 않은 일련의 삽입은 삽입 정렬 또는 인덱스 중첩 루프 조회로 볼 수 있습니다.
어쨌든이 폴백 알고리즘은 더 많은 메모리를 할당하지 않고도 결국 완료되도록 보장됩니다. b- 트리에 사용 가능한 공간이 오버 플로우 파티션의 모든 그룹화 키 및 집계를 보유하기에 충분하지 않은 경우 다중 패스가 필요할 수 있습니다.
b- 트리 인덱스를 보유하는 데 사용할 수있는 메모리가 소진되면 현재 유출 된 파티션의 추가 행이 하나의 새로운 tempdb 파티션 (더 작게 보장됨 )으로 전송 되고 필요에 따라 프로세스가 반복됩니다. 해시 재귀 가 종료 되었으므로 스필 수준은 5로 유지됩니다 . 일부 처리 세부 사항은 문서화되지 않은 추적 플래그 7357로 볼 수 있습니다.