JPA saveAll() 사용 시 Hibernate의 배치 처리(batch size) 적용 여부
MySQL의 rewriteBatchedStatements 설정을 통한 멀티로우(Multi-row) Insert 처리 방식 확인
관련 블로그: 우아한형제들 Tech 블로그 - JPA saveAll, JDBC batch, multi-row insert 성능 비교
Hibernate의 batch_size는 JPA를 통해 다량의 INSERT/UPDATE가 발생할 경우, 이를 내부적으로 모아 JDBC의 Batch로 전송하는 기능입니다.
하지만 JDBC의 Batch는 결국 단일 row SQL을 여러 번 보내는 구조이므로
MySQL에서 rewriteBatchedStatements=true 옵션이 켜져 있어야 다수의 row를 한 쿼리로 묶어 처리하는 Multi-row insert로 최적화됩니다.
설정
spring.jpa.properties.hibernate.jdbc.batch_size=20
Flush 시점까지 PreparedStatement에 addBatch() 호출
persist() 혹은 save() 할 때, 하이버네이트가 내부적으로 PreparedStatement.addBatch()에 JDBC 쿼리를 쌓는다.배치 실행 시 executeBatch() 호출
flush() 호출, 혹은 트랜잭션 종료 시점에 PreparedStatement.executeBatch()가 수행됩니다.MySQL의 멀티-로우 처리 방식
executeBatch() 시점에 여러 개의 값을 묶어 INSERT INTO ... VALUES (...),(...)… 형태로 멀티-로우 쿼리로 전송할 수 있습니다.