테마
12화 포스트모템 뒤 한빛유통도 FK를 하나씩 켜기 시작했다. 6월 3일에 첫 단계로 T_ORD_DET → M_ITM FK를 켰다(고아 0건 확인).
그 주부터 상품팀의 「상품 정보」 화면이 저장 버튼에서 멈춘다. 점심 주문이 몰리는 11:30~13:00에는 평균 41초, 길면 2분 가까이 걸리고, 새벽에는 바로 저장된다. 개발팀은 이렇게 말한다. "가격 한 칸만 바꾸는 UPDATE예요. 키는 건드리지도 않아요."
화면의 SQL은 사내 ORM 프레임워크가 만든다. 엔티티의 컬럼을 전부 SET에 넣는 기본 설정 그대로다.
M_ITM 상품(부모): 100행 · 5블록 · PK_M_ITM (ITM_ID) · 상품팀이 하루 300번쯤 저장한다T_ORD_DET 주문상세(자식): 200,000행 · 896블록 · PK_T_ORD_DET (ORD_SEQ, ORD_DET_NO) · 6월 3일에 켠 FK_ORD_DET_ITM (ITM_ID → M_ITM) ENABLED VALIDATED · ITM_ID가 맨 앞인 인덱스는 없다T_ORD 주문: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · 다른 FK는 아직 없다T_ORD와 T_ORD_DET를 INSERT한 뒤 결제창이 닫힐 때 COMMIT한다(보통 30초~2분). 점심 피크에는 COMMIT 전 주문이 늘 20~40건 있다.-- 「상품 정보」 저장: ORM 이 만든 SQL (가격 한 칸만 바꿔도 모양이 같다)
UPDATE M_ITM
SET ITM_ID = :1,
ITM_NM = :2,
ITM_TP = :3,
UNT_PRC = :4
WHERE ITM_ID = :5;
COMMIT;
[「상품 정보」 저장 한 번 — 새벽에 혼자 돌렸을 때]
FK 켜기 전 FK 켠 뒤
session logical reads 3 903 ← T_ORD_DET 896 블록을 통째로 훑는다
경과 1 ms 38 ms
[시간표 — 6월 5일 12:10 · 점심 피크 · 상품 1042 의 가격만 바꿨다]
시각 상품 화면 (SID 64) 주문 화면 (SID 131 · 152 · 177 …)
12:10:00 주문 INSERT (T_ORD · T_ORD_DET) · 결제창 — COMMIT 전
12:10:05 저장 → UPDATE M_ITM … → 기다림 (SID 131)
12:10:41 SID 131 COMMIT
12:10:41 계속 기다림 (이번엔 SID 152)
12:11:18 SID 152 COMMIT · 그다음 SID 177 …
12:11:52 UPDATE 끝 · COMMIT (1분 47초)
[V$SESSION — 12:10:30]
SID EVENT SECS BLOCKING_SESSION 하고 있는 문장
64 enq: TX - row lock contention 25 131 UPDATE M_ITM SET ITM_ID = :1, ITM_NM = :2 …
131 SQL*Net message from client 30 (결제창 — 트랜잭션을 연 채)
[V$LOCK — 12:10:30 (TM 은 객체 이름으로)]
SID TYPE 대상 LMODE REQUEST BLOCK
64 TM M_ITM 3 0 0
64 TX 상품 화면의 트랜잭션 6 0 0
64 TX SID 131 의 트랜잭션 0 4 0 ← 행 락(6)이 아니라 4
131 TM T_ORD 3 0 0
131 TM T_ORD_DET 3 0 0
131 TM M_ITM 3 0 0 ← 자식에 넣은 세션은 부모에도 TM 3
131 TX SID 131 의 트랜잭션 6 0 1
(SID 131 이 넣은 주문상세의 상품은 1077 · 1015 — 1042 가 아니다)
[같은 날 「상품 정보」 저장 312 번 — 애플리케이션 로그]
11:30 ~ 13:00 평균 41초 · 최대 1분 52초 그 밖의 시간 평균 0.04초
V$LOCK을 근거로 가격만 고친 UPDATE가 왜 T_ORD_DET를 통째로 읽고 주문 화면을 기다리는지 설명하시오.