[JPA] Batch Insert

2024. 11. 5. 23:54·Spring Framework/JPA
반응형
  • Spring Boot, Spring Data JPA, PostgreSQL 환경에서 대량 데이터를 삽입할 때 사용할 수 있는 여러 방법의 성능을 비교
    • 개별 엔티티 저장(Repository.save())
    • 엔티티 컬렉션 저장(Repository.saveAll())
    • JDBC 템플릿을 활용한 배치 삽입 (batchInsert())
  • PostgreSQL JDBC 드라이버의 reWriteBatchedInserts 옵션과 배치 크기의 영향

엔티티와 데이터를 저장하는 메서드는 다음과 같다. ID 생성 전략을 IDENTITY로 설정하면 batch 옵션이 동작하지 않으므로 주의해야 한다.

@Entity
@SequenceGenerator(
        name = "issued_coupon_code_gen",
        sequenceName = "issued_coupon_code_coupon_code_sn_seq",
        initialValue = 1,
        allocationSize = 100
)
public class IssuedCouponCode {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "issued_coupon_code_gen")
    private Long couponCodeSn;

    private String serialCode;
}

@Transactional
public void save(int size) {
    List<IssuedCouponCode> issuedCouponCodes = generateList(size);
    issuedCouponCodes.forEach(issuedCouponCodeRepository::save);
}

@Transactional
public void saveAll(int size) {
    List<IssuedCouponCode> issuedCouponCodes = generateList(size);
    issuedCouponCodeRepository.saveAll(issuedCouponCodes);
}

@Transactional
public void batchInsert(int size) {
    List<IssuedCouponCode> issuedCouponCodes = generateList(size);
    issuedCouponCodeRepository.batchInsert(issuedCouponCodes);
}

hibernate.jdbc.batch_size를 100으로 설정 후 10만건의 데이터를 추가하는데 걸리는 시간을 측정했다.

삽입 방식 reWriteBatchedInserts=false reWriteBatchedInserts=true 성능 향상
save() 6524ms 5513ms 15.5%
saveAll 5062ms 3498ms 30.9%
batchInsert 2537ms 601ms 76.3%
  • saveAll()이 save() 보다 더 좋은 성능을 보였다.
  • 모든 설정에서 JDBC 템플릿을 직접 사용해 배치 삽입을 수행하는게 가장 성능이 좋았다. → Jpa Repository를 사용할 때 발생하는 엔티티 관리와 캐싱 오버헤드 때문
  • reWriteBatchedInserts=true 설정이 전체적으로 성능을 향상시켰다.

PostgreSQL JDBC 드라이버의 reWriteBatchedInserts 가 배치 삽입 쿼리의 성능에 상당한 영향을 주는 것을 확인할 수 있었다. true로 설정할 경우 여러 개별 삽입 문을 하나의 다중 행 삽입 문으로 만들어 준다.

-- reWriteBatchedInserts=false
INSERT INTO issued_coupon_code(serial_code) VALUES('1');
INSERT INTO issued_coupon_code(serial_code) VALUES('2');
INSERT INTO issued_coupon_code(serial_code) VALUES('3');

-- reWriteBatchedInserts=true
INSERT INTO issued_coupon_code(serial_code) VALUES('1'),('2'),('3');

성능이 중요한 대량 처리 로직에서는 JPA Repository를 사용하는 것 대신 JDBC 기반의 batchInsert() 방식을 선택하는 것이 최적의 선택일 수 있다.

반응형
저작자표시 비영리 변경금지 (새창열림)
'Spring Framework/JPA' 카테고리의 다른 글
  • [JPA] orphanRemoval, CasecaseType.REMOVE
덴마크초코우유
덴마크초코우유
IT, 알고리즘, 프로그래밍 언어, 자료구조 등 정리
    반응형
  • 덴마크초코우유
    이것저것끄적
    덴마크초코우유
  • 전체
    오늘
    어제
    • 분류 전체보기 (122)
      • Spring Framework (9)
        • Spring (5)
        • JPA (2)
        • Spring Security (0)
      • Language (51)
        • Java (11)
        • Python (10)
        • JavaScript (5)
        • NUXT (2)
        • C C++ (15)
        • PHP (8)
      • DB (16)
        • MySQL (10)
        • Reids (3)
        • Memcached (2)
      • 개발 (3)
      • 프로젝트 (2)
      • Book (2)
      • PS (15)
        • 기타 (2)
        • 백준 (2)
        • 프로그래머스 (10)
      • 딥러닝 (8)
        • CUDA (0)
        • Pytorch (0)
        • 모델 (0)
        • 컴퓨터 비전 (4)
        • OpenCV (1)
      • 기타 (16)
        • 디자인패턴 (2)
        • UnrealEngine (8)
        • ubuntu (1)
        • node.js (1)
        • 블로그 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바
    map
    FPS
    Unreal
    memcached
    웹
    프로그래머스
    select
    블루프린트
    딥러닝
    NUXT
    게임
    파이썬
    언리얼엔진4
    redis
    클래스
    mscoco
    pytorch
    게임 개발
    JavaScript
    MySQL
    PS
    CPP
    Python
    C
    JS
    알고리즘
    php
    Unreal Engine
    C++
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
덴마크초코우유
[JPA] Batch Insert
상단으로

티스토리툴바