테마
유통 본사의 「일 마감」 프로시저는 매일 새벽 매장마다 전날 판매 건수와 금액을 세어 마감 테이블에 넣는다. 2019년에 작성됐고, 변수 타입은 손으로 적었다.
올해 스케줄러 서버를 바꾼 뒤로 본사 리포트에 지난달 마감이 하루도 나오지 않는다. 리포트는 CLOSE_DT LIKE '202311%'로 마감을 찾는다. 새 스케줄러 서버의 세션은 NLS_LANG=KOREAN_KOREA라서 NLS_DATE_FORMAT이 RR/MM/DD다. 오과장은 원인을 찾는 김에 프로시저의 TKPROF도 떠 왔다.
CF10 판매: 500,000행 · 4,583블록(전체 스캔 4,511) · SLE_DT VARCHAR2(8) · SHP_NO NUMBER(5) · 하루 약 700건(매장마다 약 140건)CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO)CF07 매장: 6행(판매가 있는 매장은 5곳) · SHP_NO NUMBER(5)T_SHP_DAY_CLOSE 일 마감(이 문제에서 쓰는 파생 테이블): CLOSE_DT VARCHAR2(8) ('YYYYMMDD') · SHP_NO NUMBER(5) · SLE_CNT · SLE_AMT · 하루 6행IX_CF10_SLE_DT (SLE_DT): BLEVEL 2 · 리프 1,393 · CF 9,921 · 통계 최신PROCEDURE P_DAY_CLOSE(p_base_dt IN DATE) IS -- 스케줄러가 TRUNC(SYSDATE) - 1을 넘긴다
v_ymd NUMBER(8) := TO_NUMBER(TO_CHAR(p_base_dt, 'YYYYMMDD'));
v_cnt NUMBER;
v_amt NUMBER;
BEGIN
FOR s IN (SELECT TO_CHAR(SHP_NO) AS shp_no FROM CF07) LOOP
-- ① 매장의 그날 판매 건수
SELECT COUNT(*) INTO v_cnt
FROM CF10
WHERE SLE_DT = v_ymd
AND SHP_NO = s.shp_no;
-- ② 매장의 그날 판매 금액
SELECT NVL(SUM(b.SLE_QTY * b.SLE_UPRC), 0) INTO v_amt
FROM CF10 a, CF11 b
WHERE a.SLE_DT = v_ymd
AND a.SHP_NO = s.shp_no
AND b.SLE_NO = a.SLE_NO;
-- ③ 마감 저장
INSERT INTO T_SHP_DAY_CLOSE (CLOSE_DT, SHP_NO, SLE_CNT, SLE_AMT)
VALUES (p_base_dt, s.shp_no, v_cnt, v_amt);
END LOOP;
COMMIT;
END;
[TKPROF 요약 · P_DAY_CLOSE(DATE '2023-11-30') 한 번]
① SELECT COUNT(*) FROM CF10 WHERE SLE_DT = :B2 AND SHP_NO = :B1
Execute 6 · Fetch 6 · query 27,066 · rows 6
② SELECT NVL(SUM(B.SLE_QTY * B.SLE_UPRC), 0) FROM CF10 A, CF11 B WHERE A.SLE_DT = :B2 AND A.SHP_NO = :B1 AND B.SLE_NO = A.SLE_NO
Execute 6 · Fetch 6 · query 29,886 · rows 6
③ INSERT INTO T_SHP_DAY_CLOSE (CLOSE_DT, SHP_NO, SLE_CNT, SLE_AMT) VALUES (:B4, :B3, :B2, :B1)
Execute 6 · query 0 · current 18 · rows 6
[① 1번 매장 실행 때 · DBMS_XPLAN.DISPLAY_CURSOR]
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.03 | 4511 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.03 | 4511 |
|* 2 | TABLE ACCESS FULL| CF10 | 1 | 1000 | 141 |00:00:00.03 | 4511 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("SHP_NO"=TO_NUMBER(:B1) AND TO_NUMBER("SLE_DT")=:B2))
[마감 테이블 · 새 서버에서 돈 2023-11-30분]
CLOSE_DT SHP_NO SLE_CNT SLE_AMT
-------- ------ ------- ----------
23/11/30 1 141 1,826,500
23/11/30 2 139 1,794,000
...