테마
정산팀의 「금액 구간별 PG 수수료」는 2024년 주문을 월마다 PG사 수수료 구간표에 맞춰 구간별 건수, 금액, 수수료를 낸다. 재무팀이 구간별 건수를 더해 보니 333,516건으로, 그해 주문 333,245건보다 271건 많아 반려했다.
개발자는 해시 조인이 빠르다며 USE_HASH를 달았는데 실행계획에는 MERGE JOIN이 나온다. 박팀장은 "숫자부터 맞추고, 조인도 제대로 정리해 달라"라고 했다.
T_ORD_BIG: 1,000,000행 · 5,826블록 · 인덱스 없음 · 2024년 주문 333,245건 · ORD_AMT는 10,000 ~ 500,000원 사이 100원 단위 (서로 다른 값 4,901개, 값마다 2024년에 약 68건)T_FEE_BAND PG 수수료 구간표 (이 문제에서 쓰는 파생 테이블): 5행 · 4블록 · BAND_CD · LO_AMT · HI_AMT · FEE_RTHI_AMT와 다음 구간의 LO_AMT가 같다 (PG사 계약서: "하한 이상, 상한 미만")SELECT /*+ USE_HASH(o b) */
TO_CHAR(o.ORD_DT, 'YYYYMM') AS ym, b.BAND_CD,
COUNT(*) AS ord_cnt, SUM(o.ORD_AMT) AS ord_amt,
SUM(o.ORD_AMT * b.FEE_RT) AS fee_amt
FROM T_ORD_BIG o, T_FEE_BAND b
WHERE o.ORD_DT >= DATE '2024-01-01'
AND o.ORD_DT < DATE '2025-01-01'
AND o.ORD_AMT BETWEEN b.LO_AMT AND b.HI_AMT
GROUP BY TO_CHAR(o.ORD_DT, 'YYYYMM'), b.BAND_CD
---------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 60 |00:00:00.71 | 5830 | | | |
| 1 | HASH GROUP BY | | 1 | 60 | 60 |00:00:00.71 | 5830 | 1270K| 1270K| 1123K (0)|
| 2 | MERGE JOIN | | 1 | 8331 | 333K|00:00:00.62 | 5830 | | | |
| 3 | SORT JOIN | | 1 | 5 | 5 |00:00:00.01 | 4 | 2048 | 2048 | 2048 (0)|
| 4 | TABLE ACCESS FULL | T_FEE_BAND | 1 | 5 | 5 |00:00:00.01 | 4 | | | |
|* 5 | FILTER | | 5 | | 333K|00:00:00.55 | 5826 | | | |
|* 6 | SORT JOIN | | 5 | 333K| 1087K|00:00:00.47 | 5826 | 9876K| 1101K| 8778K (0)|
|* 7 | TABLE ACCESS FULL| T_ORD_BIG | 1 | 333K| 333K|00:00:00.06 | 5826 | | | |
---------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("O"."ORD_AMT"<="B"."HI_AMT")
6 - access(INTERNAL_FUNCTION("O"."ORD_AMT")>=INTERNAL_FUNCTION("B"."LO_AMT"))
filter(INTERNAL_FUNCTION("O"."ORD_AMT")>=INTERNAL_FUNCTION("B"."LO_AMT"))
7 - filter(("O"."ORD_DT">=TO_DATE(' 2024-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"O"."ORD_DT"<TO_DATE(' 2025-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
[결과 대조] 구간별 건수 합계 333,516 · 2024년 주문 333,245 · 차이 271
USE_HASH가 무시된 이유도 설명하시오.