테마
유통 본사 MD팀은 분기마다 「연간 상품별 매장별 판매」를 병렬로 뽑는다. 2021년에 만든 SQL에는 분배 방식을 고정한 힌트가 붙어 있고, 그때부터 DOP 2로 돌았다. 올해 분석 DB 서버를 늘리면서 DOP를 8로 올렸는데, 6.1초 걸리던 것이 8.4초로 늘었고 TEMP 사용량 경보가 울렸다. 판매상품은 지난해 데이터팀이 판매번호 해시 8칸 복사본으로 다시 만들어 두었다. 박팀장: "분배 방식 몇 가지를 비교하고, 판매 테이블 설계까지 바꿀 가치가 있는지 판단해서 가져와."
CF10_P 판매(파티션 복사본, 문제 설정): CF10 500,000행을 PARTITION BY RANGE (SLE_DT) 월별 24칸(P202201 ~ P202312)과 빈 PMAX로 나눴다. 2023년은 13 ~ 24번째 칸이고 약 250,000행, 2,292블록이다. 보관 기간이 지난 달은 DROP PARTITION으로 정리한다.CF11_H 판매상품(분석 복사본, 문제 설정): CF11 1,096,708행을 PARTITION BY HASH (SLE_NO) PARTITIONS 8로 CTAS했다. 판매일 컬럼이 없어 연도로 칸을 고를 수 없다. 8칸 전체는 약 8,208블록이다. 2023년 판매의 판매상품은 약 548,000행이다.SLE_NO다. 매장 5곳 × 상품 109개라서 결과는 545행이다. 인덱스는 이 조회에 쓰이지 않는다.-- 2021.05 · DOP 2 에서 분배 방식을 고정했다
SELECT /*+ LEADING(s h) USE_HASH(h) PQ_DISTRIBUTE(h BROADCAST NONE) PARALLEL(8) */
s.SHP_NO, h.ITM_NO, SUM(h.SLE_QTY) AS qty, SUM(h.SLE_QTY * h.SLE_UPRC) AS amt
FROM CF10_P s, CF11_H h
WHERE s.SLE_DT BETWEEN '20230101' AND '20231231'
AND h.SLE_NO = s.SLE_NO
GROUP BY s.SHP_NO, h.ITM_NO
------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | A-Rows | Buffers | Used-Mem | Used-Tmp | Pstart | Pstop | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 545 | 10500 | | | | | | | |
| 1 | PX COORDINATOR | | 1 | 545 | 10500 | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 8 | 545 | 10500 | | | | | Q1,02 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 8 | 545 | 10500 | 389K | | | | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 8 | 4360 | 10500 | | | | | Q1,02 | PCWP | |
| 5 | PX SEND HASH | :TQ10001 | 8 | 4360 | 10500 | | | | | Q1,01 | P->P | HASH |
| 6 | HASH GROUP BY | | 8 | 4360 | 10500 | 412K | | | | Q1,01 | PCWP | |
|* 7 | HASH JOIN | | 8 | 548K | 10500 | 5952K (1) | 11M | | | Q1,01 | PCWP | |
| 8 | PX RECEIVE | | 8 | 2000K | 2292 | | | | | Q1,01 | PCWP | |
| 9 | PX SEND BROADCAST | :TQ10000 | 8 | 2000K | 2292 | | | | | Q1,00 | P->P | BROADCAST |
| 10 | PX BLOCK ITERATOR | | 8 | 250K | 2292 | | | 13 | 24 | Q1,00 | PCWC | |
|* 11 | TABLE ACCESS FULL | CF10_P | 104 | 250K | 2292 | | | 13 | 24 | Q1,00 | PCWP | |
| 12 | PX BLOCK ITERATOR | | 8 | 1096K | 8208 | | | 1 | 8 | Q1,01 | PCWC | |
| 13 | TABLE ACCESS FULL | CF11_H | 104 | 1096K | 8208 | | | 1 | 8 | Q1,01 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("H"."SLE_NO"="S"."SLE_NO")
11 - filter(("S"."SLE_DT">='20230101' AND "S"."SLE_DT"<='20231231'))
(Used-Mem · Used-Tmp 은 서버 하나의 값 · 서버 여덟이 같은 크기의 해시 테이블을 따로 짓는다)
[같은 SQL · DOP 2 (지난 분기) 와 DOP 8 (이번 분기)]
DOP 2 DOP 8
경과 6.1초 8.4초
TQ10000 이 보낸 판매 행 500,000 2,000,000 (25만 × 서버 수)
서버 하나의 해시 작업 영역 약 25 MB 약 6 MB
해시 조인 메모리 안 (0) 원패스 (1) · 서버마다 TEMP 약 11 MB · 합계 약 88 MB