테마
한빛유통 정산팀은 매주 보정 요청 엑셀(약 12,000줄)을 관리 화면(Spring Boot, JPA)에 올린다. 화면은 줄마다 보정 요청 엔티티를 만들어 saveAll로 한꺼번에 저장한다. 업로드가 10초 가까이 걸려서 가끔 화면의 제한 시간(10초)을 넘긴다.
개발자는 블로그 글을 보고 hibernate.jdbc.batch_size=500을 넣었지만 9.8초가 9.6초가 됐을 뿐이다. "배치 크기를 넣었으니 500줄씩 묶여 나가야 하는데요?"
T_STLM_ADJ_REQ 보정 요청(이 문제에서 쓰는 테이블): REQ_ID NUMBER GENERATED BY DEFAULT AS IDENTITY(PK) · STLM_SEQ · ADJ_AMT · REQ_DT · REQ_USER · 지금 31만 행, 주에 약 12,000행씩 는다 · 다른 프로그램은 이 테이블에 넣지 않는다REQ_ID는 업무 의미가 없는 키다(화면과 보고서는 STLM_SEQ로 찾는다).// AdjReq.java : 키는 DB의 IDENTITY 칸이 매긴다
@Entity
@Table(name = "T_STLM_ADJ_REQ")
public class AdjReq {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "REQ_ID")
private Long reqId;
private Long stlmSeq;
private BigDecimal adjAmt;
private LocalDateTime reqDt;
private String reqUser;
}
# application.properties (지난주 추가)
spring.jpa.properties.hibernate.jdbc.batch_size=500
// AdjUploadService.java
@Transactional
public void upload(List<AdjRow> rows) {
repo.saveAll(rows.stream().map(AdjReq::from).collect(toList())); // 12,040건
}
[업로드 한 번 (12,040줄) · 세션 통계 증가분]
경과 시간 9.6 초
execute count 12,046
SQL*Net roundtrips to/from client 12,051
session logical reads 49,812
SQL*Net message from client 12,050번 · 6.9 초
[V$SQL]
SQL_TEXT EXECUTIONS ROWS_PROCESSED
insert into T_STLM_ADJ_REQ (adj_amt, req_dt, req_user, stlm_seq) values
(:1 , :2 , :3 , :4 ) RETURNING REQ_ID INTO :5 12,040 12,040
[한 번 실행] INSERT STATEMENT → LOAD TABLE CONVENTIONAL · Buffers 4 (테이블 블록, PK 인덱스 리프)
batch_size를 넣었는데도 INSERT가 묶이지 않은 것을 위 숫자로 확인하고, 왜 묶이지 않았는지 설명하시오.