테마
버거 본사 BI팀은 월요일 밤 「매장별 일 매출」 리포트를 빠르게 하려고 ORD에 인덱스 두 개를 만들었다(리포트 22,422 → 380블록). 화요일 11:50부터 전국 매장 POS의 결제 완료가 수십 초씩 걸렸고, 점장들의 전화가 본사로 몰렸다. 운영팀은 "DB CPU는 20%라 한가하다"고 했다.
POS는 결제 버튼을 누르면 주문과 주문상품을 넣고, 카드 승인 응답을 받은 뒤 COMMIT한다(보통 1~2초). 점심 피크에는 매장 200곳이 1분에 300건 남짓 결제한다.
ORD 주문: 1,000,000행 · 22,422블록 · ORD_NO NUMBER · ORD_DT VARCHAR2(8) · SHOP_NO VARCHAR2(10) ('SH0001' ~ 'SH0200') · ORD_PK (ORD_NO) · ORD_X01 (ORD_DT, ORD_HMS)ORD_BX01 BITMAP (ORD_DT) · ORD_BX02 BITMAP (SHOP_NO)ORD_ITEM 주문상품: 2,472,717행 · 55,265블록 · ORD_ITEM_PK (ORD_NO, ITEM_ID) · ORD_ITEM_X01 (ORD_DT, ORD_HMS) (비트맵 없음)-- POS 결제 (매장 200곳 · 계산대마다)
INSERT INTO ORD (ORD_NO, ORD_DT, ORD_HMS, SHOP_NO)
VALUES (:ord_no, TO_CHAR(SYSDATE, 'YYYYMMDD'), TO_CHAR(SYSDATE, 'HH24MISS'), :shop_no);
INSERT INTO ORD_ITEM (ORD_NO, ITEM_ID, ORD_ITEM_QTY, ORD_DT, ORD_HMS)
VALUES (:ord_no, :item_id, :qty, TO_CHAR(SYSDATE, 'YYYYMMDD'), TO_CHAR(SYSDATE, 'HH24MISS')); -- 상품마다
-- 카드 승인 응답을 기다린다 (1 ~ 2초)
COMMIT;
-- 「매장별 일 매출」 리포트 (하루 두 번)
SELECT o.SHOP_NO, o.ORD_DT, COUNT(*) AS ord_cnt
FROM ORD o
WHERE o.SHOP_NO IN (:s1, :s2, :s3, :s4, :s5)
AND o.ORD_DT BETWEEN :from_dt AND :to_dt
GROUP BY o.SHOP_NO, o.ORD_DT;
-- 월요일 밤 BI 팀
CREATE BITMAP INDEX ORD_BX01 ON ORD (ORD_DT);
CREATE BITMAP INDEX ORD_BX02 ON ORD (SHOP_NO);
[ASH — 화요일 11:50 ~ 12:20 · 상위 이벤트]
EVENT 표본 % SQL
enq: TX - row lock contention 4,812 81% INSERT INTO ORD (ORD_NO, ORD_DT, ORD_HMS, SHOP_NO) VALUES (:1, …)
CPU 702 12%
log file sync 298 5%
(INSERT INTO ORD_ITEM 의 enq: TX 표본은 0 이다)
[V$LOCK — 12:05:12 · POS 세션 일부]
SID TYPE 대상 LMODE REQUEST BLOCK
407 TM ORD 3 0 0
407 TX SID 407 의 트랜잭션 6 0 1 ← SH0081 · 카드 승인 응답을 기다리는 중 (COMMIT 전)
512 TX SID 407 의 트랜잭션 0 4 0 ← SH0117 의 주문
388 TX SID 407 의 트랜잭션 0 4 0 ← SH0042 의 주문
611 TX SID 512 의 트랜잭션 0 4 0 ← SH0117 의 다른 계산대
… REQUEST 4 로 기다리는 POS 세션 41개
[POS 결제 한 건 — 점심 피크]
지난주 화요일 평균 1.4초 (거의 카드 승인)
이번 화요일 평균 23초 · 최대 71초 · 결제 포기(타임아웃 60초) 186건
[리포트 — BI팀의 측정] 인덱스 전 TABLE ACCESS FULL 22,422블록 → 인덱스 뒤 BITMAP AND · 380블록
V$LOCK을 근거로 서로 다른 매장의 주문 INSERT가 왜 한 줄로 서는지 설명하시오. ORD_ITEM INSERT는 왜 기다리지 않는지도 쓰시오.