테마
본사 레거시 유통의 물류팀은 매장 상품별로 하루 사이에 재고가 얼마나 줄었는지 보려고, 재고 이력 CF18_HIS에 전일 재고 칸(PRV_INV_QTY)을 만들었다. 2년 치를 채우는 UPDATE를 개발 서버에서 돌렸더니 11초 넘게 걸렸다. 물류팀은 재고 실사 정정이 들어올 때마다 이 문장을 다시 돌리겠다고 한다.
개발자: "앞 날짜의 재고를 가져오는 서브쿼리가 PK를 타니까 문제없을 줄 알았어요."
CF18_HIS 일별상품재고 이력(이 문제를 위해 둔 파생 테이블, 일반 힙 테이블): CF18과 같은 컬럼(SHP_NO · ITM_NO NUMBER · INV_BS_DT VARCHAR2(8) · INV_QTY)에 PRV_INV_QTY NUMBER(지금은 모두 NULL)를 더했다 · 매장 5곳 × 상품 109개 × 730일 = 397,850행 · 1,720블록CF18_HIS_PK (SHP_NO, ITM_NO, INV_BS_DT) · BLEVEL 2. 다른 인덱스는 없다.PCTFREE 20) 만든 테이블이라 칸을 채워도 행 이전은 생기지 않는다. 통계는 최신이다.UPDATE CF18_HIS h
SET h.PRV_INV_QTY =
(SELECT p.INV_QTY -- 같은 매장 · 상품의 바로 앞 날짜 재고
FROM CF18_HIS p
WHERE p.SHP_NO = h.SHP_NO
AND p.ITM_NO = h.ITM_NO
AND p.INV_BS_DT = (SELECT MAX(q.INV_BS_DT)
FROM CF18_HIS q
WHERE q.SHP_NO = h.SHP_NO
AND q.ITM_NO = h.ITM_NO
AND q.INV_BS_DT < h.INV_BS_DT));
COMMIT;
--------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
--------------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | | 0 |00:00:11.42 | 3191K |
| 1 | UPDATE | CF18_HIS | 1 | | 0 |00:00:11.42 | 3191K |
| 2 | TABLE ACCESS FULL | CF18_HIS | 1 | 397K| 397K|00:00:00.05 | 1720 |
| 3 | TABLE ACCESS BY INDEX ROWID | CF18_HIS | 397K| 1 | 397K|00:00:06.88 | 2784K |
|* 4 | INDEX UNIQUE SCAN | CF18_HIS_PK | 397K| 1 | 397K|00:00:05.61 | 2387K |
| 5 | SORT AGGREGATE | | 397K| 1 | 397K|00:00:02.47 | 1194K |
| 6 | FIRST ROW | | 397K| 1 | 397K|00:00:02.03 | 1194K |
|* 7 | INDEX RANGE SCAN (MIN/MAX)| CF18_HIS_PK | 397K| 1 | 397K|00:00:01.71 | 1194K |
--------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("P"."SHP_NO"=:B1 AND "P"."ITM_NO"=:B2 AND "P"."INV_BS_DT"=
(SELECT MAX("Q"."INV_BS_DT") FROM "CF18_HIS" "Q" WHERE "Q"."INV_BS_DT"<:B3 AND "Q"."ITM_NO"=:B4 AND "Q"."SHP_NO"=:B5))
7 - access("Q"."SHP_NO"=:B1 AND "Q"."ITM_NO"=:B2 AND "Q"."INV_BS_DT"<:B3)
[세션 통계] 갱신된 행 397,850 · 경과 11.4초
Starts로 설명하시오.