Spring Boot 성능 최적화 2

2025. 10. 27. 20:35·TIL

JPA 자체 성능 최적화

JPA는 개발 생산성이 높지만 내부 동작을 이해하지 못하면 성능 문제를 일으키기 쉽다.
이 글에서는 Spring Boot + JPA 환경에서 실무적으로 자주 활용되는 JPA 자체 성능 최적화 전략들을 정리한다.


#영속성 컨텍스트(Persistence Context) 이해하기

영속성 컨텍스트는 JPA의 핵심이며 성능 최적화와 직접 관련된다.

영속성 컨텍스트가 수행하는 기능은 다음과 같다.

  • 1차 캐시 관리
  • 동일성 보장
  • 변경 감지(Dirty Checking)
  • flush 시점 관리

문제가 생기는 이유
조회한 모든 엔티티가 캐시에 보관되며, 변경 감지를 위해 스냅샷이 유지되기 때문이다.
대량 조회 시 메모리를 크게 소모하고 flush 시점마다 모든 엔티티를 비교하게 된다.

최적화 전략

  • 단순 조회는 DTO로 조회
  • 읽기 전용은 @Transactional(readOnly = true) 적용
  • 대량 처리 시 batch flush + clear 적용
for (int i = 0; i < items.size(); i++) {
    process(items.get(i));
    if (i % 50 == 0) {
        em.flush();
        em.clear();
    }
}

#Batch Size로 N+1 완화하기

N+1을 Fetch Join으로 해결하기 어렵거나 페이징이 필요한 상황에서는 Batch Size가 가장 효과적이다.

Batch Size 동작 방식

연관된 엔티티를 모아서 IN 쿼리로 조회한다.
예: 100개 조회 → BatchSize 50 → 2번의 IN 쿼리로 해결

설정 방법

application.yml

spring:
  jpa:
    properties:
      hibernate.default_batch_fetch_size: 100

엔티티 개별 설정

@BatchSize(size = 50)
@OneToMany
private List<Comment> comments;

#Dirty Checking 최소화

Dirty Checking은 JPA의 장점이지만 성능 비용이 크다.
트랜잭션 범위 내 모든 엔티티를 추적하고 flush 시점마다 비교하기 때문이다.

최적화 전략

  • 조회 트랜잭션에는 `readOnly = true` 적용
  • 대량 UPDATE → 벌크 쿼리 사용
  • UPDATE만 필요하면 엔티티 조회 없이 바로 JPQL 사용

벌크 업데이트 예시

@Modifying
@Query("update Member m set m.status = :status where m.id in :ids")
void updateStatus(...);

#DTO 기반 조회로 select * 피하기

불필요하게 엔티티를 로딩하면 영속성 컨텍스트를 낭비하고 성능이 떨어진다.
목록/통계 조회는 DTO로 직접 조회하는 것이 정답이다.

select new com.example.MemberSummary(m.id, m.name)
from Member m
where m.active = true

장점:
- 조회 속도 향상
- 네트워크 트래픽 감소
- 1차 캐시 메모리 절약


#FlushMode 조정

기본 FlushModeType.AUTO는 SELECT 실행 전에도 flush가 발생해 성능이 느려질 수 있다.

개선 방법

em.setFlushMode(FlushModeType.COMMIT);

트랜잭션 커밋 시점에만 flush 되므로 불필요한 flush 비용이 줄어든다.


#연관관계 Fetch 전략 최적화

OneToMany를 EAGER로 두면 예상치 못한 대량 로딩이 발생해 성능이 크게 떨어진다.

기본 규칙

  • 모든 연관관계 기본은 LAZY
  • 필요한 경우에만 Fetch Join 또는 BatchSize 사용

마치며

JPA 자체 성능 최적화는 DB 최적화보다 난이도는 높지만 효과는 크다.
핵심 포인트는 다음과 같다.

  • 영속성 컨텍스트를 이해하고 필요한 경우에만 엔티티 조회
  • Batch Size로 N+1 완화
  • Dirty Checking 최소화
  • DTO 기반 조회로 엔티티 남용 방지

다음 글에서는 캐시(Cache) 기반 성능 최적화를 다룰 예정이다.

'TIL' 카테고리의 다른 글

Spring Boot 성능 최적화 4  (0) 2025.10.29
Spring Boot 성능 최적화 3  (0) 2025.10.28
Spring Boot 성능 최적화 1  (0) 2025.10.25
10/24  (0) 2025.10.24
10/23  (1) 2025.10.23
'TIL' 카테고리의 다른 글
  • Spring Boot 성능 최적화 4
  • Spring Boot 성능 최적화 3
  • Spring Boot 성능 최적화 1
  • 10/24
twodc
twodc
매일의 배움과 고민, 그리고 작은 성장을 담은 개발자의 성장일지입니다.
  • twodc
    The Answer is 42
    twodc
  • 전체
    오늘
    어제
    • 분류 전체보기 (122)
      • TIL (122)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
twodc
Spring Boot 성능 최적화 2
상단으로

티스토리툴바