테마
이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.
이커머스 포인트 적립 API(Python, python-oracledb)는 point_transactions에 한 건씩 넣는다. 평소에는 분당 300건쯤이고, 지난 토요일 쿠폰 이벤트 때는 분당 9,000건이었다. 그 두 시간 동안 DB 대기 상위에 cursor: mutex X와 library cache: mutex X가 올랐고 API 응답이 1초를 넘겼다.
개발팀이 말했다. "바인드 변수도 쓰고 SQL은 한 줄뿐이에요. 하드 파싱이 생길 리가 없어요."
point_transactions: 45,000행 · 210블록 · PK(tx_id)만 · customer_id NUMBER · amount NUMBER · tx_type VARCHAR2(10)order_id NUMBER(NULL 허용, 쿠폰 적립은 NULL)와 memo VARCHAR2(200)(비어 있거나 10 ~ 150자) 컬럼이 더 있다seq_point_tx CACHE 1000 · DB 문자셋 AL32UTF8# point_api.py
SQL = """INSERT INTO point_transactions (tx_id, customer_id, amount, tx_type, order_id, memo, created_at)
VALUES (seq_point_tx.NEXTVAL, :cust, :amt, :tp, :ord, :memo, SYSDATE)"""
def earn(cur, cust, amt, ord_id=None, memo=None):
cur.execute(SQL, cust=cust, amt=amt, tp="EARN", ord=ord_id, memo=memo)
# 주문 확정 : earn(cur, 1234, 500, ord_id=88123)
# 쿠폰 이벤트 : earn(cur, body["customer_id"], 1000, memo=body["msg"]) # "1234" · 메시지 길이 제각각
[V$SQLAREA — 토요일 15:00] VERSION_COUNT 14 · LOADS 23 · EXECUTIONS 412,880 · SHARABLE_MEM 1.9MB
[V$SQL_SHARED_CURSOR — Y 칸 세기 (자식 14개)] BIND_MISMATCH 9 · BIND_LENGTH_UPGRADEABLE 4
[V$SQL_BIND_CAPTURE — 자식 셋만]
CHILD :CUST :ORD :MEMO 호출 경로
0 NUMBER NUMBER VARCHAR2(32) 주문 확정 (memo 없음)
3 VARCHAR2(32) VARCHAR2(32) VARCHAR2(128) 쿠폰 · 짧은 메시지 (ord 없음)
7 VARCHAR2(32) VARCHAR2(32) VARCHAR2(2000) 쿠폰 · 긴 메시지
[AWR — 토요일 14:00 ~ 16:00 · Top Timed Events]
cursor: mutex X 21%
DB CPU 38%
library cache: mutex X 9%
parse count (hard) 이 문장 23번 · 다른 문장 합계 40번
[한 번 실행의 계획]
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
---------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | | 0 |00:00:00.01 | 7 |
| 1 | LOAD TABLE CONVENTIONAL | POINT_TRANSACTIONS | 1 | | 0 |00:00:00.01 | 7 |
| 2 | SEQUENCE | SEQ_POINT_TX | 1 | | 1 |00:00:00.01 | 0 |
---------------------------------------------------------------------------------------------------------