Skip to content

Conversation

@Dimo-2562
Copy link
Contributor

@Dimo-2562 Dimo-2562 commented Jan 7, 2026

❤️ 기능 설명

Spring Batch의 PostSummaryWriter에서 JPA saveAll() 대신 JDBC Batch 쿼리를 사용하여 게시글 요약 및 키워드 저장 시 DB 쿼리 수를 대폭 감소시켰습니다.

주요 변경사항

1. JdbcBatchExecutor 유틸리티 생성 (src/main/java/com/techfork/global/util/JdbcBatchExecutor.java)

범용 JDBC Batch 실행 유틸리티 클래스 생성:

@Component
public class JdbcBatchExecutor {
    // 배치 INSERT
    public <T> int batchInsert(String sql, List<T> items, BatchParameterSetter<T> setter)

    // 배치 UPDATE
    public <T> int batchUpdate(String sql, List<T> items, BatchParameterSetter<T> setter)

    // 배치 DELETE
    public <T> int batchDelete(String sql, List<T> items, BatchParameterSetter<T> setter)

    @FunctionalInterface
    public interface BatchParameterSetter<T> {
        void setValues(PreparedStatement ps, T item, int index) throws SQLException;
    }
}

특징:

  • JdbcTemplate.batchUpdate() 기반
  • 함수형 인터페이스로 유연한 파라미터 설정
  • INSERT/UPDATE/DELETE 통합 처리
  • 처리된 행 수 로깅 및 반환
  1. PostSummaryWriter 완전 리팩토링 (src/main/java/com/techfork/domain/post/batch/PostSummaryWriter.java:25)

AS-IS (JPA):

@Override
public void write(Chunk<? extends Post> chunk) {
    postRepository.saveAll(chunk.getItems());
    // 100개 게시글 × 11개 쿼리 = 1,100개 쿼리
}

TO-BE (JDBC Batch):

@Override
public void write(Chunk<? extends Post> chunk) {
    List<? extends Post> posts = chunk.getItems();

    updatePostSummaries(posts);    // 1번의 Batch UPDATE
    deleteOldKeywords(posts);      // 1번의 Batch DELETE
    insertNewKeywords(posts);      // 1번의 Batch INSERT

    entityManager.clear();         // 영속성 컨텍스트로 인한 추가 쿼리 방지
    // 100개 게시글 → 3개 쿼리로 완료
}

세부 구현:

  1. updatePostSummaries(): 모든 게시글의 summary 필드를 배치 UPDATE
    UPDATE posts SET summary = ? WHERE id = ?

  2. deleteOldKeywords(): 모든 게시글의 기존 키워드를 배치 DELETE
    DELETE FROM post_keywords WHERE post_id = ?

  3. insertNewKeywords(): 모든 새 키워드를 배치 INSERT
    INSERT INTO post_keywords (keyword, post_id) VALUES (?, ?)

  4. entityManager.clear(): 영속성 컨텍스트 클리어로 추가 쿼리 방지

  5. PostBatchWriter 클래스명 통일 (src/main/java/com/techfork/domain/source/batch/PostBatchWriter.java:25)

  • 기존 JdbcBulkInsert → JdbcBatchExecutor로 변경
  • 일관된 네이밍으로 코드 가독성 향상

성능 개선 효과

100개 게시글, 각 5개 키워드 시:

구분 기존 (JPA) 개선 (JDBC Batch) 개선율
UPDATE 쿼리 100개 1개 (배치) 99% 감소
DELETE 쿼리 500개 1개 (배치) 99.8% 감소
INSERT 쿼리 500개 1개 (배치) 99.8% 감소
총 쿼리 수 1,100개 3개 99.7% 감소
예상 처리 시간 ~5-10초 ~0.5초 미만 90% 이상 단축

부가 효과:

  • DB 커넥션 획득/해제 횟수: 1,100회 → 3회
  • 네트워크 Round-trip: 1,100회 → 3회
  • 메모리 사용량 감소 (EntityManager 클리어)
  • 대량 데이터 처리 안정성 향상

연결된 issue

close #148

✅ 체크리스트

  • PR 제목 규칙 잘 지켰는가?
  • 추가/수정사항을 설명하였는가?
  • 테스트 결과 사진을 넣었는가?
  • 이슈넘버를 적었는가?

참고 사이트

https://docs.spring.io/spring-framework/reference/6.2/data-access/jdbc/advanced.html

@Dimo-2562 Dimo-2562 self-assigned this Jan 7, 2026
@Dimo-2562 Dimo-2562 added 🌟 REFACTOR 리팩터링 (기능 변화 X) 🏢 domain:source 테크블로그 출처 labels Jan 7, 2026
@Dimo-2562 Dimo-2562 merged commit 8427747 into develop Jan 7, 2026
1 check passed
@Dimo-2562 Dimo-2562 deleted the refactor/#148 branch January 7, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🏢 domain:source 테크블로그 출처 🌟 REFACTOR 리팩터링 (기능 변화 X)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] JDBC Template Batch 쿼리를 활용한 대량 데이터 처리 성능 개선

2 participants