테마
한빛유통은 매월 1일 PG사가 보내는 정정 파일을 받으면 지난 결제 전체(주문 10만 건)를 다시 대사한다. 대사 규칙(결제 수단별 허용 오차, 등급별 예외)은 결제 화면과 같은 패키지 PKG_PAY_RULE에 있고, 결제팀이 매달 고친다. 지난달에는 규칙 안에 PG사 공지 테이블을 읽는 줄이 들어갔다가 빠졌다.
결과는 대사 결과 테이블에 적고, 맞지 않는 주문은 보류(HOLD)로 바꾼다. 박팀장이 TKPROF를 넘기며 말했다. "한 문장으로 다 바꾸자는 말도 나오는데, 규칙을 SQL로 옮기면 결제 화면과 두 벌이 돼요. 어떻게 할지 숫자로 정리해 줘요."
T_ORD 주문: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · PAY_TP · ORD_AMT · PAY_AMT · ORD_STT_ORD_DET 주문상세: 200,000행 · 896블록 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO) · 주문당 1 ~ 3건M_CUS 고객: 2,000행 · 30블록 · PK_M_CUS (CUS_ID) · 모든 주문의 고객이 있다T_PAY_RECON(대사 결과, 이 문제용): RECON_YM · ORD_SEQ · RES_CD · 인덱스 없음 · 회차마다 그 달 것을 지우고 다시 쓴다(이번이 이달 첫 회차)PKG_PAY_RULE.CHECK_PAY: 지금은 SQL 없는 PL/SQL 함수 · 이번 달 결과 'OK' 99,588건 · 'HOLD' 412건PROCEDURE PAY_RECON(p_ym VARCHAR2) IS
v_gd M_CUS.CUS_GD%TYPE;
v_det NUMBER;
v_res VARCHAR2(10);
BEGIN
DELETE FROM T_PAY_RECON WHERE RECON_YM = p_ym;
FOR r IN (SELECT ORD_SEQ, CUS_ID, PAY_TP, ORD_AMT, PAY_AMT FROM T_ORD) LOOP
SELECT CUS_GD INTO v_gd FROM M_CUS WHERE CUS_ID = r.CUS_ID; -- ①
SELECT NVL(SUM(ORD_QTY * UNT_PRC), 0) INTO v_det
FROM T_ORD_DET WHERE ORD_SEQ = r.ORD_SEQ; -- ②
v_res := PKG_PAY_RULE.CHECK_PAY(r.PAY_TP, v_gd, r.ORD_AMT, r.PAY_AMT, v_det);
UPDATE T_ORD
SET ORD_ST = CASE WHEN v_res = 'OK' THEN ORD_ST ELSE 'HOLD' END
WHERE ORD_SEQ = r.ORD_SEQ; -- ③
INSERT INTO T_PAY_RECON (RECON_YM, ORD_SEQ, RES_CD)
VALUES (p_ym, r.ORD_SEQ, v_res); -- ④
END LOOP;
COMMIT;
END;
[TKPROF 요약 — PAY_RECON('202412') 한 번 · sys=no]
문장 Execute Fetch rows query current elapsed
구동 커서 SELECT … FROM T_ORD 1 1,001 100,000 1,897 0 0.05
① SELECT CUS_GD FROM M_CUS WHERE CUS_ID = :B1 100,000 100,000 100,000 300,000 0 0.41
② SELECT NVL(SUM(ORD_QTY*UNT_PRC),0) FROM T_ORD_DET … 100,000 100,000 100,000 300,412 0 0.49
③ UPDATE T_ORD SET ORD_ST = CASE … WHERE ORD_SEQ = :B2 100,000 0 100,000 200,000 102,871 1.36
④ INSERT INTO T_PAY_RECON … VALUES (:B3, :B2, :B1) 100,000 0 100,000 211 102,946 0.88
(DELETE는 이달 첫 회차라 0행)
[세션 통계 — 한 번]
경과 시간 4.6 초 · CPU 4.2 초 · recursive calls 401,038 · session logical reads 1,008,749
redo size 54.6 MB · undo change vector size 17.9 MB
결과: OK 99,588건 · HOLD 412건
INSERT … SELECT와 UPDATE) 판과 비교해 이 판을 고른 근거와, 고친 판의 부작용을 쓰시오.