Skip to content
튜닝 연습DML과 배치 튜닝
DML-009

포인트 소급 적립 5,604건에 12초, 대기 1위가 log file sync다

기초INSERT이커머스434 / 700

이 문제는 교재 18화 졸업 과제와 같은 이커머스 데이터베이스를 씁니다. 『튜너의 1년』을 순서대로 읽고 있다면 졸업 과제를 먼저 풀고 오세요. 아래 「테이블과 인덱스」 칸에 과제의 답 일부(제약 조건, 인덱스, 통계의 실제 상태)가 나옵니다.

상황 ​

CRM팀은 적립 정책을 바꾸면서 2024년에 배송 완료된 주문에 주문 금액의 1%를 소급 적립하기로 했다. 개발자가 만든 Java 프로그램은 대상 주문을 한 번에 읽어 온 뒤 한 건씩 INSERT를 보낸다. 시험 DB에서 5,604건에 11.8초가 걸렸고, 세션의 대기 이벤트 1위는 log file sync였다. 개발자: "DB 서버 디스크가 느린 거 아닐까요?"

테이블과 인덱스 ​

  • orders: 34,908행 · 193블록 · status 6종(DELIVERED가 약 80%) · 2024년 DELIVERED 5,604건
  • point_transactions: 45,000행 · 210블록 · PK tx_id(시퀀스 seq_tx_id)만 있다.
  • JDBC 연결은 기본값(autocommit 켜짐) 그대로다. 앱 서버와 DB 서버 사이 왕복은 약 0.4ms다.

원본 SQL ​

sql
// PointBackfill.java (CRM팀) — 연결은 기본값: autocommit = true
List<Row> rows = jdbc.query(
    "SELECT order_id, customer_id, total_amount FROM orders " +
    " WHERE status = 'DELIVERED' " +
    "   AND order_date >= DATE '2024-01-01' AND order_date < DATE '2025-01-01'");

for (Row r : rows) {                       // 5,604 번
    jdbc.update(
        "INSERT INTO point_transactions (tx_id, customer_id, amount, tx_type, created_at) " +
        "VALUES (seq_tx_id.NEXTVAL, ?, ?, 'EARN', SYSDATE)",
        r.customerId, Math.round(r.totalAmount * 0.01));
}

실행계획 학습용 예시 ​

xplan
[세션 통계 · 대기 이벤트 — 프로그램 한 번 (V$SESSTAT · V$SESSION_EVENT 증가분)]
  경과 시간                           11.8 초
  execute count                       5,607
  user commits                        5,604
  SQL*Net roundtrips to/from client   5,611
  redo size                           약 3.3 MB

  EVENT                          WAITS    TIME(s)   AVG(ms)
  log file sync                  5,604      6.28      1.12
  SQL*Net message from client    5,611      4.71      0.84
  (DB CPU                                   0.64)

문제 ​

  1. log file sync가 무엇을 기다린 시간인지, 이 프로그램에서 왜 5,604번이나 기다렸는지 설명하시오.
  2. 같은 적립을 하도록 고치고, 고친 뒤의 숫자를 적으시오. 프로그램을 남겨야 할 때의 방법도 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자