테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스 앱은 매일 10:00에 「출석 체크」 이벤트를 열고, 버튼을 누른 회원에게 포인트를 적립한다. 10:00부터 2분 동안 적립이 몰리는데(약 60세션, 초당 150건), 그때만 적립 API가 3초를 넘긴다.
적립 번호 tx_id는 시퀀스 SQ_POINT_TX에서 받는다. 시퀀스를 만든 외주 개발사의 인수 문서에는 이렇게 적혀 있다. "포인트 거래번호는 건너뛰면 안 되므로 NOCACHE ORDER로 생성함."
point_transactions: 45,000행 · 210블록 · PK tx_id · customer_id · amount · tx_type(EARN · USE · EXPIRE) · created_atSQ_POINT_TX: NOCACHE ORDER · 데이터베이스는 단일 인스턴스(RAC 아님)point_transactions INSERT 한 번과 COMMIT이다-- 외주 개발사가 만든 시퀀스 (인수 문서)
CREATE SEQUENCE SQ_POINT_TX START WITH 1 NOCACHE ORDER;
-- 적립 API — 버튼 한 번
INSERT INTO point_transactions (tx_id, customer_id, amount, tx_type, created_at)
VALUES (SQ_POINT_TX.NEXTVAL, :customer_id, 10, 'EARN', SYSDATE);
COMMIT;
[AWR — 10:00 ~ 10:05 · 적립 18,420건]
Top 대기 이벤트
EVENT WAITS TIME(s) AVG(ms) %DB time
enq: SQ - contention 16,904 1,183 70 57.9
row cache lock 4,310 237 55 11.6
DB CPU 411 20.1
log file sync 18,460 92 5 4.5
SQL ordered by Executions (같은 구간)
EXECUTIONS SQL
18,420 INSERT INTO POINT_TRANSACTIONS (TX_ID, …) VALUES (SQ_POINT_TX.NEXTVAL, …)
18,420 update seq$ set increment$=:2, minvalue=:3, … where obj#=:1 ← 재귀 SQL
[적립 한 건 — 혼자 돌렸을 때 세션 통계]
recursive calls 5
db block changes 8 (point_transactions 와 PK 2 · SEQ$ 2 · 언두 4)
redo size 1,412 bytes (그중 SEQ$ 갱신 몫 약 650)
[DBA_SEQUENCES — 10:05]
SEQUENCE_NAME CACHE_SIZE ORDER_FLAG LAST_NUMBER
SQ_POINT_TX 0 Y 63,421