본문 바로가기

IT/JPA

JPA BatchSize에 대해 알아보자

오늘은 JPA BatchSize에 대해 간단히 알아 보겠습니다.

Jpa BatchSize란

  • BatchSize 는 JPA 의 성능 개선을 위한 옵션 중 하나입니다.
  • 데이터의 전체 row를 예상할 수 있는 범위에서는 좋은 방안이긴 하나 정확한 Size를 알수 없을때는 적정값을 설정해 주긴 어렵습니다.
  • 그리고 연관관계의 있는 엔티티의 1+N 이슈의 한 해결 방법이기도 합니다.
  • 다수의 프록시 객체를 조회할 때 WHERE 절이 같은 여러 개의 SELECT 쿼리들을 하나의 IN 쿼리로 만들어줍니다.

- Entity

Team 엔티티 Member 엔티티를 1:N의 연관관계를 맺어 보겠습니다.

- BatchSize

@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface BatchSize {
    /**
     * Strictly positive integer.
     */
    int size();
}

@BatchSize 클래스 정의로 가보시면 보면 위과 같이 나와있습니다.

Type, Method, Field 에 사용할 수 있으며 size 를 설정해야 합니다.

size 는 간단히 말해서 IN 절에 들어갈 요소의 최대 갯수를 의미합니다. 이 size가 정확한 값이 없습니다.

만약 IN 절에 size 보다 더 많은 요소가 들어가야 한다면 여러 개의 IN 쿼리로 나누어 날립니다.

- Entity 클래스에 @BatchSize애노테이션 설정

@BatchSize(size = 100)
@Entity
class Team( 
)

Entity 클래스 위에 붙여서 사용 가능하십니다.

만약 다른 엔티티에서 여러 개의 Team 객체를 프록시로 호출한다면 배치사이즈가 적용되어 IN 쿼리로 조회할 겁니다.

- 필드에 @BatchSize애노테이션 설정

@Entity
class Team {
    @BatchSize(size = 100)
    @OneToMany(mappedBy = "team")
    val member:List<Member>
}

@OneToMany 를 사용하는 컬렉션에 사용하시면 여러 Team 객체가 getMember() 호출할 때 하나의 쿼리로 가져옵니다.

- application.yml에 설정

spring:
    properties:
      hibernate:
        default_batch_fetch_size: 50

application.yml 에 추가하면 프로젝트 전역으로 배치 사이즈를 적용할 수 있습니다.

- 테스트

var team:List<Team> = temmRepository.findAll()

team.get(0).getMember().size()

Team, Member 데이터가 데이터베이스에 있다는 전제로 진행합니다.

Team 에서 for 문으로 간단하게 작성해도 되지만 명시적으로 쿼리를 날려 보겠습니다.

- BatchSize가 적용되지 않은 경우

select * from team

select * from member where member.team_id=21
select * from member where member.team_id=22

배치 사이즈를 적용하지 않으면 Member 테이블을 조회하기 위해 두 개의 쿼리가 날아갑니다.

만약 Team team의 데이터 수 만큼 조회를 하게 됩니다.

- BatchSize가 적용된 경우

select * from team

select * from member where member.team IN (21, 22)

배치 사이즈를 추가하면 여러 쿼리를 하나의 IN 쿼리로 만들어줍니다.

IN 절에 들어가는 요소의 갯수는 설정 가능합니다.

만약 조건 갯수보다 설정한 배치사이즈 크기가 더 작다면 IN 쿼리가 추가로 날아갑니다. 적절한 설정이 필요한 것입니다.

예를 들어 size 를 50 으로 설정했기 때문에 데이터가 150 개라면 1 ~ 50, 51 ~ 100, 101 ~ 150 이렇게 세 번에 나누어서 IN 쿼리를 날립니다.

사이즈를 분배하는 법은 다른 블로그에서 살펴 보시기 바랍니다. 전에 봤던 기억이 있는데 링크가 생각나질 않네요

정리

오늘은 BatchSize에 대해 알아보았습니다. BatchSize 옵션을 사용하면 비슷한 조회 쿼리 데이터들을 한번에 가져올 수 있어 성능적으로 효과를 볼 수 있습니다.