티스토리 뷰

@BatchSize

연관된 엔티티를 조회할 때 지정한 size 만큼 where 조건의 in 절으로 조회한다.
 
 

1:N 관계의 Entity 정의

정의 조건
: 1명의 멤버는 여러 개의 주문을 가질 수 있다.
Members (1) : Orders (N)
 

* 부모 class : Members

@Entity
class Members(
    @Column(nullable = false, length = 50)
    var email: String,
    @Column(nullable = false, length = 20)
    var name: String,
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @OneToMany(mappedBy = "Members", fetch = FetchType.LAZY)
    var orders = mutableListOf<Orders>()
}


* 자식 class : Orders

@Entity
class Orders(
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    var member: Members,
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null
}




 

@BatchSize 사이즈에 따라 실행되는 쿼리

먼저 root 쿼리로 회원을 조회한다.

select * from members --가장 먼저 회원 10명 조회

 
회원이 10명이면 회원에 따른 주문도 10번 조회된다.

select * from orders where member_id=1 --회원과 연관된 주문
select * from orders where member_id=2 --회원과 연관된 주문
select * from orders where member_id=3 --회원과 연관된 주문
select * from orders where member_id=4 --회원과 연관된 주문
select * from orders where member_id=5 --회원과 연관된 주문
...
--10개 실행

 
N+1문제 발생! 이를 BatchSize 설정으로 해결할 수 있다!
 

batchSize=5 로 설정했다.

지연 로딩 (fetch = FetchType.LAZY) 은 엔티티를 최초 사용하는 시점에 자식 엔티티까지 한번에 조회하기 때문에
설정해둔 배치 사이즈 5건의 데이터를 미리 로딩해둔다.
 
예를들어, 주문에 대해 조회한 회원이 10명이고, batchSize=5 로 설정하면 where in() 이 적용된 2번의 쿼리문이 추가로 실행된다.
1+N 에서 1+2 로 전환된 것이다.
 
그리고 6번째 데이터를 사용하면 쿼리문을 추가로 실행한다.

select * from orders
where member_id in (?, ?, ?, ?, ?)

 
 

@BatchSize 어노테이션 설정 위치

부모 클래스, 즉 @ToMany 어노테이션을 가진 곳에 붙인다.
 
entity class, field, application 전체에 설정할 수 있다.


Entity Class

@BatchSize(size = 5)
@Entity
class Members(
    @Column(nullable = false, length = 50)
    var email: String,
    @Column(nullable = false, length = 20)
    var name: String,
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @OneToMany(mappedBy = "Members", fetch = FetchType.LAZY)
    var orders = mutableListOf<Orders>()
}




 

Field

@Entity
class Members(
    @Column(nullable = false, length = 50)
    var email: String,
    @Column(nullable = false, length = 20)
    var name: String,
) {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    var id: Long? = null

    @BatchSize(size = 5)
    @OneToMany(mappedBy = "Members", fetch = FetchType.LAZY)
    var orders = mutableListOf<Orders>()
}

 

 

Application 전체

hibernate.default_batch_fetch_size 속성으로 application 전체에 @BatchSize를 적용할 수 있다.

- properties

〈property name=”hibernate.default_batch一fetch_size" value="100" />

- yml

spring:
    properties:
      hibernate:
        default_batch_fetch_size: 100




 
 
 
 

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함