default_batch_fetch_size

1. default_batch_fetch_size란?

 

Hibernate의 default_batch_fetch_size는 한 번에 로드되는 엔티티나 컬렉션의 크기를 지정

 

이 설정은 지연 로딩(LAZY) 상태의 엔티티나 컬렉션을 가져올 때 최소한의 SELECT 쿼리를 사용하도록 도움

 

작동 원리:

  • 예를 들어, 100개의 Post가 있고, 각 Post가 여러 개의 Image와 연관되어 있다고 가정
  • 기본적으로 LAZY 로딩에서는 각 Post에 대해 개별적인 SELECT 쿼리가 실행(N+1 문제 발생).
  • 하지만 default_batch_fetch_size를 100으로 설정하면, Hibernate는 최대 100개의 Post의 Image를 한 번의 SELECT 쿼리로 가져옴

 


2. 설정 방법

application.yml 또는 application.properties에 설정

 

application.yml 예시

spring:
  jpa:
    properties:
      hibernate:
        default_batch_fetch_size: 100

 

3. 적용 대상

default_batch_fetch_size는 다음 경우에 적용

  • @OneToMany (예: Post -> Image)
  • @ManyToOne (예: Image -> Post)
  • @ManyToMany

 

Hibernate는 연관된 엔티티를 배치로 로딩하여 N+1 문제를 완화

 


4. 배치 크기 설정의 적정값

  • 일반적으로 50~100 사이로 설정하는 것이 좋음
  • 값이 너무 크면:
    • 한 번에 가져오는 데이터가 많아져 메모리 사용량 증가.
  • 값이 너무 작으면:
    • 배치 페치의 이점이 줄어듭니다(여전히 다수의 쿼리가 실행될 수 있음).

 

5. 예제

엔티티 관계

@Entity
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @OneToMany(mappedBy = "post", fetch = FetchType.LAZY)
    private List<Image> images;
}

@Entity
public class Image {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String url;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "post_id")
    private Post post;
}

 

쿼리 실행

List<Post> posts = queryFactory
        .selectFrom(post)
        .where(post.createdDate.before(LocalDateTime.now()))
        .fetch();

// 연관된 이미지 가져오기 (배치 페치 적용)
for (Post post : posts) {
    List<Image> images = post.getImages(); // 여기에 배치 페치 적용
}

 

Hibernate는 default_batch_fetch_size에 따라 Post와 관련된 Image를 한 번에 가져옴


 

6. 결론

 

default_batch_fetch_size: 100 설정은 성능 최적화에 유용하며,

 

특히 연관 관계가 많은 경우 N+1 문제를 줄이는 데 효과적

 

다만, 배치 크기를 적절히 설정해야 하며, 실제 데이터에 따라 쿼리 로그를 확인하면서 성능 테스트를 진행하는 것이 좋음.