테마
구매팀의 「거래처 납품 상품 판매 실적」은 거래처를 고르면 그 거래처에 발주한 적이 있는 상품들의 한 달 판매 수량과 매출을 보여 준다. 처음에 IN 서브쿼리로 짰던 SQL을 이번 달 개편 때 조민우가 조인으로 바꿨다. "발주 쪽 컬럼(최근 발주일)을 나중에 화면에 붙이려고" 바꿨다고 한다.
개편 뒤 첫 보고에서 재무팀이 매출이 판매 원장과 맞지 않는다며 반려했다. 상품마다 어긋난 정도가 37배에서 61배까지 제각각이라, 처음에는 단가 오류를 의심했다.
CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · SLE_NO가 'YYYYMMDD-NNNN' 모양이라 한 달 범위는 CF11_PK로 읽는다(2023년 6월 46,384줄 · 리프 181블록 · 테이블 347블록)CF12 발주: 734행 · 10블록 · CF12_PK (ORD_NO) · 거래처 :ptnr의 발주 61건CF13 발주상품: 7,102행 · 57블록 · CF13_PK (ORD_NO, ITM_NO) · 거래처 :ptnr의 발주 61건에 상품 12종이 590줄(상품마다 37 ~ 61줄)SELECT b.ITM_NO,
SUM(b.SLE_QTY) AS qty,
SUM(b.SLE_QTY * b.SLE_UPRC) AS amt
FROM CF11 b, CF13 d, CF12 h
WHERE b.SLE_NO >= :v_from -- '20230601'
AND b.SLE_NO < :v_to -- '20230701'
AND d.ITM_NO = b.ITM_NO
AND h.ORD_NO = d.ORD_NO
AND h.PTNR_NO = :ptnr
GROUP BY b.ITM_NO
ORDER BY amt DESC
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 12 |00:00:00.24 | 595 |
| 1 | SORT ORDER BY | | 1 | 12 | 12 |00:00:00.24 | 595 |
| 2 | HASH GROUP BY | | 1 | 12 | 12 |00:00:00.24 | 595 |
|* 3 | HASH JOIN | | 1 | 311K| 311K|00:00:00.13 | 595 |
|* 4 | HASH JOIN | | 1 | 590 | 590 |00:00:00.01 | 67 |
|* 5 | TABLE ACCESS FULL | CF12 | 1 | 61 | 61 |00:00:00.01 | 10 |
| 6 | TABLE ACCESS FULL | CF13 | 1 | 7102 | 7102 |00:00:00.01 | 57 |
| 7 | TABLE ACCESS BY INDEX ROWID BATCHED| CF11 | 1 | 46384 | 46384 |00:00:00.02 | 528 |
|* 8 | INDEX RANGE SCAN | CF11_PK | 1 | 46384 | 46384 |00:00:00.01 | 181 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("D"."ITM_NO"="B"."ITM_NO")
4 - access("H"."ORD_NO"="D"."ORD_NO")
5 - filter("H"."PTNR_NO"=:PTNR)
8 - access("B"."SLE_NO">=:V_FROM AND "B"."SLE_NO"<:V_TO)
SUM(DISTINCT …)로 더하는 안, (다) 발주 쪽을 상품당 한 줄로 먼저 만든 뒤 조인하는 안, (라) 원래의 IN 서브쿼리로 돌아가는 안의 결과와 일량을 비교하시오.