본문 바로가기
Tech/JPA

JPA Batch 연산 적용

반응형

1. Bulk(Batch) Insert

  • 같은 테이블에 대한 다수의 insert를 한 번에 입력하는 것
  • 단 건 입력
    
    # 개별 INSERT 
    INSERT INTO relation_item (id, name, price) VALUES (?, ?, ?);
    INSERT INTO relation_item (id, name, price) VALUES (?, ?, ?);
    INSERT INTO relation_item (id, name, price) VALUES (?, ?, ?);
  • Bulk(Batch) Insert
    
    # Bulk insert
    INSERT INTO relation_item (id, name, price) 
    VALUES 
        (?, ?, ?)
        ,(?, ?, ?)
        ,(?, ?, ?)
        ,(?, ?, ?);

 

2. 그럼 왜 insert를 Bulk insert로 바꾸려 하는가?

  • 하나의 쿼리를 실행할 때는 그 전후로 이루어지는 작업이 발생한다 ( Transaction 관련, Index 관련 등등 )
  • 따라서 MySQL 옵티마이저 쿼리 최적화 방법 중에는 이런 내용이 있다
insert속도를 최적화하기 위해서는, 여러개의 작은 연산을 하나의 큰 연산으로 합쳐라. 이론상으로, 하나의 커넥션을 만들고, 한번에 다수의 행에대한 데이터를 보내고, 모든 index 업데이트,  consistency checking를 끝날때까지 지연시킨다.

* consistency checking: 내부 데이터 충돌이 있는지 확인

 

3. Spring Data JPA Bulk insert 적용

  • MySQL Driver 옵션 추가
    
    // MySQL Connection Option
    rewriteBatchedStatements=true
  • JPA batch size 추가
    
    // batch fetch size
    spring.jpa.properties.hibernate.default_batch_fetch_size: 1000
  • 제약 사항
    • 결론만 말씀드리면 내가 하려던 곳에는 벌크 insert를 하지 못했다
    • 사용하고자 하는 엔티티의 Key 생성방식이 @GeneratedValue(strategy = GenerationType.IDENTITY) 이기 때문
      • GenerationType.IDENTITY 방식이란 MySQL의 경우 AUTO_INCREMENT를 통해 ID를 증가시키며 할당
      • 즉 INSERT를 실행하기 전까지 ID를 알 수 없기 때문에 쓰기 지연을 활성화 시킬 수 없다
      • 쓰기 지연을 통해 Batch insert를 수행해야하는 하이버네이트의 경우는 결국 Batch insert/update를 수행하지 못함

 

4. MySQL General Query 로그

  • IDE Console에 찍히는 JDBC 로그 혹은 JPA(Hibernate) 로그를 통해 위 벌크 연산이 진행되는지 알 수 도 있지만 좀 더 정확하게 실제 수행된 쿼리 로그만 보고 싶은 경우 MySQL의 General Query 로그를 활성화시켜 볼 수 있다
  • General Query 로그
    • MySQL 접근
      
      // Login MySQL
      mysql -u root -p
    • General Query 로그 확인
      
      // SHOW General log
      show variables like 'general_log%';
    • General Query 로그 활성화
      set global general_log = 'ON';​


 

728x90
반응형