본문 바로가기
Spring

[Spring] Bulk Insert 성능 개선

by 가드 2022. 11. 27.
728x90

이전에 Querydsl Bulk Update 성능 개선 글을 포스팅했고 이번에는 Bulk Insert에 대한 내용을 다루려고 한다. 아마 Querydsl의 블로그 마지막 편이 아닐까 싶다. 좋은 공부 거리가 있으면 다시 포스팅할 수도...

JDBC에는 rewirteBatchedStatements라고 해서 Insert 합치기 옵션이 있다. 이 옵션이 활성화되어 있어도 JPA에서는 auto_increment 일 때 Insert 합차기 기능이 적용되지 않는다.

JPA를 이용한 Bulk Insert와 JDBC를 이용한 Bulk Insert를 비교해보자.

1. JPA Bulk Insert

public void jpaBulkInsert() {
    List<Item> bulk = Lists.newArrayList();
    for(int i = 1; i <= 10000; i++) {
        bulk.add(Item.builder().itemNo((long) i).itemName("name " + i).build());
    }
    itemRepository.saveAll(bulk);
}

2. JDBC Bulk Insert

public void jdbcBulkInsert(List<Item> bulk) {
    String sql = "insert into item (itemNo, itemName) values (?, ?)";
    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            ps.setLong(1, bulk.get(i).getItemNo());
            ps.setString(2, bulk.get(i).getItemName());
        }

        @Override
        public int getBatchSize() {
            return bulk.size();
        }
    });
}

1만 건 기준으로 테스트 진행하였다.

- JPA Bulk Insert 처리시간 : 3 sec 462ms

- JDBC Bulk Insert 처리시간 : 518ms

JPA Merge 사용하든 혹은 JPA persist를 사용하든 JDBC Batch를 사용했을 때 보다 성능이 많이 떨어진다.

위의 성능으로만 따져 봤을 때 JPA bulk insert 보다는 jdbcTemplate로 bulk insert는 하는 방식 좋으나 jdbcTemplate 사용하게 되면 문자열로 쿼리를 작성해야 해서 문법 체크, 코드와 테이블 간의 불일치 체크, 타입 체크 등의 확인이 어려워 관리에 대한 불편함을 준다.

 

개발자가 코드 관리 차원에서 생각하면 JDBC Batch 방식을 사용하고 싶지 않으나 성능 차이가 너무 심해서 대량에 Bulk Insert에만 사용해야 하나 싶다. 상황에 맞게 고려해서 사용하는 게 정답인 거 같다.

 

 

 

 

300x250

댓글