테마
매달 1일 03:00에는 지난달 미결제 주문(PENDING)을 취소(CANCEL)로 바꾸는 정리 배치가 돈다. 7월 1일에 6월분 2,191건을 정리하는 데 1분 32초가 걸렸다.
배치 담당 오과장: "겨우 2천 건인데요. UPDATE 한 건에 0.04초면 빠른 편 아닌가요?"
T_ORD_BIG: 1,000,000행 · 5,826블록. PK가 없고, ORD_SEQ는 값은 유일하지만 인덱스가 없다.IX_ORD_BIG_DT_AMT (ORD_DT, ORD_AMT) 하나다(정산 기간 조회 Q1용).PENDING은 2,191건(8%)이다. 통계는 최신이다.-- 매월 1일 03:00 · 지난달 미결제 주문 정리 (오과장)
BEGIN
FOR r IN (SELECT ORD_SEQ
FROM T_ORD_BIG
WHERE ORD_DT >= DATE '2024-06-01'
AND ORD_DT < DATE '2024-07-01'
AND ORD_ST = 'PENDING') LOOP
UPDATE T_ORD_BIG
SET ORD_ST = 'CANCEL'
WHERE ORD_SEQ = r.ORD_SEQ;
END LOOP;
COMMIT;
END;
[세션 통계 — 7월 1일 03:00 실행]
경과 시간 1분 32초 (거의 전부 CPU)
session logical reads 12,777,640
recursive calls 2,236
갱신한 행 2,191
[V$SQL — 루프 안의 UPDATE]
SQL_TEXT EXECUTIONS ROWS_PROCESSED BUFFER_GETS ELAPSED
UPDATE T_ORD_BIG SET ORD_ST = 'CANCEL' WHERE ORD_SEQ = :B1 2,191 2,191 12,771,339 91.4 초
[그 UPDATE 한 번의 실행계획 — DISPLAY_CURSOR (ALLSTATS LAST)]
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | | 0 |00:00:00.04 | 5829 |
| 1 | UPDATE | T_ORD_BIG | 1 | | 0 |00:00:00.04 | 5829 |
|* 2 | TABLE ACCESS FULL| T_ORD_BIG | 1 | 1 | 1 |00:00:00.04 | 5826 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ORD_SEQ"=:B1)
V$SQL로 설명하시오.ORD_SEQ에 인덱스를 만들어 루프를 그대로 두는 안과 비교하시오.