SQL) 병렬 처리 Ⅱ

jinsung·2026년 1월 20일

SQL

목록 보기
44/46
post-thumbnail

2. 병렬 Order by와 Group by

1. 병렬 Order by

order by를 병렬로 수행하려면 테이블 큐를 통한 데이터 재분배가 필요한데, 쿼리 수행이 완료된 직후에 같은 세션에서 v$pq_tqstat를 쿼리해 보면 테이블 큐를 통한 데이터 전송 통계를 확인해 볼 수 있다.

병렬 쿼리 수행 속도가 빠르지 않다면 테이블 큐를 통한 데이터 전송량에 편차가 크지 않은지 확인할 필요가 있는데, 이때 v$pq_tqstat가 유용하다.


2. 병렬 Group by

order by와 group by를 병렬로 처리하는 내부 수행원리는 기본적으로 같다.

병렬 hash group by (group by)와 병렬 sort group by (group by + order by)는 데이터 분배 방식의 차이가 있다.
group by 키 정렬 순서에 따라 분배하느냐, 해시 함수 결과 값에 따라 분배하느냐의 차이이다.

결과 집합을 QC에게 전달할 때도, sort group by는 값 순서대로 QC(ORDER)이 나타나고 hash group by는 먼저 처리가 끝난 순서대로 QC(RANDOM)가 나타난다.

✅ Group by가 두 번 나타날 때의 처리 과정

병렬 group by 시 실행계획에 group by가 두 번 나타나는 경우가 있다.
그 이유는 group by 하는 컬럼의 선택도에 있다.

선택도가 높은 컬럼을 group by 컬럼에 두면 첫 번째 서버 집합이 읽은 데이터를 먼저 group by 하고 나서 두 번째 서버 집합에 전송해 프로세스 간 통신량을 줄여 병렬 처리 과정에서 생기는 병목을 줄일 수 있다.

선택도가 낮은 컬럼으로 group by 할 때도 강제로 이 방식을 사용하게 하려면 _groupby_nopushdown_cut_ratio 파라미터를 0으로 하면 된다.

11g부터는 gby_pushdown, no_gby_pushdown 힌트가 추가돼 파라미터 변경 없이도 사용자가 group by 방식을 조정할 수 있다.


3. 병렬 조인

병렬 조인 메커니즘은, 병렬 프로세스들이 서로 독립적으로 조인을 수행할 수 있도록 데이터를 분배하는 것이 중요하다.
분배작업이 완료되면 프로세스 간에 서로 방해받지 않고 각자 할당받은 범위 내에서 조인을 완료한다.

병렬 조인 방식은 두 가지가 있다.

1. 파티션 방식

Partition-Pair끼리 조인을 수행한다.

1. Full Partition Wise 조인 - 둘 다 같은 기준으로 파티션된 경우

조인에 참여하는 두 테이블이 조인 컬럼에 대해 같은 기준으로 파티셔닝돼 있는 경우이다.

다른 병렬 조인은 두 개의 서버집합이 필요하지만 , 여기서는 하나의 서버집합만 필요하다.
Full Partition Wise 조인은 파티션 기반 Granule이므로 서버 프로세스 개수는 파티션 개수 이하로 제한된다.

파티션 방식은 리스트이든 Range이든 해시이든 두 테이블이 조인 컬럼에 대해 같은 방식, 같은 기준으로 파티셔닝 돼 있다면 서로 방해받지 않고 Partition Pair 끼리 독립적인 병렬 조인이 가능하기 때문에 상관없다.

조인 방식도 NL 조인, 소트 머지 조인, 해시 조인 모두 사용 가능하다.

2. Partial Parition Wise 조인 - 둘 중 하나만 파티셔닝된 경우

둘 중 한 테이블만 조인 컬럼에 대해 파티셔닝된 경우, 다른 한쪽 테이블을 같은 기준으로 동적으로 파티셔닝하고 나서 각 Partition-Pair를 독립적으로 병렬 조인하는 것을 말한다.
둘 다 파티셔닝 돼 있지만 파티션 기준이 서로 다른 경우도 이 방식으로 조인한다.

한쪽을 동적으로 파티셔닝하기 위해서는 데이터 재분배가 선행되어야 한다.
즉, Inter-Operation parallelism을 위해 두 개의 서버 집합이 필요하다.

3. 동적 파티셔닝 - 둘 다 파티셔닝되지 않은 경우

이 경우 오라클은 두 가지 방식 중 하나를 사용한다.

  • 양쪽 테이블을 동적으로 파티셔닝하고 Full Partition Wise 조인

    첫 번째 서버 집합은 데이터를 분배하는 역할이고, 두 번쨰 서버 집합은 받은 데이터를 파티셔닝하는 역할을 한다.
    메모리 공간이 가득차면 Temp 테이블스페이스를 활용해 파티셔닝을 한다.
    양쪽을 동적으로 파티셔닝하니 때문에 두 테이블 다 데이터 재분배가 일어난다.
  1. 첫 번째 서버 집합이 테이블을 읽어 두 번째 서버집합에게 전송한다.

  2. 첫 번째 서버 집합이 다른 테이블을 읽어 두 번째 서버집합에게 전송한다.

  3. 양쪽 테이블 모두의 파티셔닝을 담당한 두 번째 서버집합이 각 Partition-Pair에 대해 독립적으로 병렬 조인을 수행한다.

양쪽 동적 파티셔닝의 특징은 조인을 본격적으로 수행하기전 메모리 자원과 Temp 테이블스페이스 공간을 많이 사용하는 것이다.
양쪽 다 파티셔닝 하므로 양쪽 테이블 모두에 대한 전체범위처리가 불가피하다.

결론적으로 양쪽 동적 파티셔닝은 어느 한 쪽도 조인 컬럼 기준으로 파티셔닝되지 않은 상황에서 두 테이블 모두 대용량 테이블이고 조인 컬럼의 데이터 분포가 균일할 때 유용한 병렬 조인 방식이다.

  • 한쪽 테이블을 Broadcast 하고 나서 조인

    두 테이블 중 작은 쪽을 반대편 서버 집합의 "모든" 프로세스에 Broadcast하고 나서 조인을 수행하는 방식이다.
  1. 첫 번째 서버 집합에 속한 프로세스들이 각자 읽은 작은 테이블의 레코드를 두 번째 서버 집합에 속한 모든 병렬 프로세스에게 전송한다.

  2. 두 번째 서버 집합에 속한 프로세스들이 각자 맡은 범위의 큰 테이블을 읽으면서 병렬로 조인을 수행한다.
    1번이 완료되면 두 번째 서버집합에 속한 프로세스 모두 작은 테이블의 완전한 집합을 갖게 되므로 프로세스 간 상호간섭 없이 독립적으로 조인 수행이 가능하다.

양쪽 테이블 모두 파티션되지 않았을 때 1차적으로 Broadcast 방식을 고려한다.
=>한쪽 테이블이 매우 작을 때
Broadcast 이후 조인할 때 NL, 소트 머지, 해시 조인 모두 가능하다.
작은 테이블은 Broadcast 하기 때문에 전체범위처리가 불가피하지만 큰 테이블은 부분 범위 처리가 가능하다.

profile
Data Engineer

0개의 댓글