Batch Size?
1:N 관계 ( 여기서는 Order : OrderItem 이라고 가정 )에서의 지연 로딩 시에 SQL 문이 각각의 N개의 객체에 대해서
select
orderItem0_.order_item_id as order_item_id5_5_1_,
orderItem0_.order_id as order_id_it1_5_1_,
orderItem0_.item_id as item_id_it1_5_0,
orderItem0_.order_price as order_price_id5_5_0,
orderItem0_.count as count_id5_3_0
from
orderItem orderItem0_
where
orderitem0_.order_id = ?
where 절에 = 이 들어가서 N개의 SQL이 나가서 orderItem을 가져오게 만드는 기본 hibernate 설정을
where 절에 IN 을 사용하여 1개의 SQL문으로 쿼리 수를 최적화 되도록 설정해주는 것이다
과장해보자면 비슷한 조회 쿼리 데이터를 한방 쿼리로 만들 수 있다
select
orderItem0_.order_item_id as order_item_id5_5_1_,
orderItem0_.order_id as order_id_it1_5_1_,
orderItem0_.item_id as item_id_it1_5_0,
orderItem0_.order_price as order_price_id5_5_0,
orderItem0_.count as count_id5_3_0
from
orderItem orderItem0_
where
orderitem0_.order_id in (
?, ? # 1관계인 order의 개수
)
IN 안에 들어가는 element의 개수가 Batch Size이다
정리하자면 적절한 상황에서 쿼리 수를 줄이기 위해 SQL 구문의 IN이 필요하다면 Batch Size 설정을 해주면 된다.
size 크기 설정
size가 100 인 경우 IN 안에 100개씩 끊어서 넣게된다
예를 들어 Order가 200개라면
- id 0 ~ id 99 까지 IN -> SQL 1번
- id 100 ~ 199 까지 IN -> SQL 1번
(정확하게 100개씩 끊어서 넣지는 않는다고 한다 JPA가 내부적으로 최적화된 size를 판단하고 100만 넘지 않는다는게 batch size)
Batch Size의 크기는 사용하고 있는 DB가 얼마나 견딜 수 있는가를 판단하여 결정
application 메모리에는 결국 다 가져와야해서 상관이 없지만
IN 절 안에 있는 element와 관련된 모든 data 들을 DB가 처리해야 하므로 결국, DB의 성능에 따라 결정
인프런 갓영한님 강의에서는 sizesms 100 ~ 1000 사이를 추천한다고 함
( DB의 종류에 따라 IN 절의 size를 최대 1000개로 제한하는 DB도 있다고 함)
적용 방법
global 하게 적용 to application.yml
jpa.properties.hibernate 에 default_batch_fetch_size를 설정해준다
이에 따라 모든 지연 로딩 프록시 객체를 만나면 100 사이즈로 IN SQL을 써서 가져온다
jpa:
hibernate:
ddl-auto: create # create 인 경우 계속 data를 drop 시킴 / none 계속 data를 drop시키지 않음
properties:
hibernate:
# show_sql: true <-운영환경에서는 system out이 아닌 다 log를 통해 찍어야 함
format_sql: true
default_batch_fetch_size: 100
Entity에 적용
N (여기서는 OrderItem) 대상인 entity에 적용해준다
해당 entity를 부를 때만 batch size가 적용된 IN SQL로 가져온다
@BatchSize(size = 100)
@Entity
public class OrderItem{
...
}
Field에 적용
1 (여기서는 Order) 대상인 entity의 @OneToMany field 에 적용한다
Order에서 해당 collection을 가져올 때, batch size가 적용되어 IN SQL로 가져올것이다
@Entity
@RequiredArgsContructor
public class Order{
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems = new ArrayList<>();
}
Batch Size 설정은 1:N 컬렉션 조인에서
1 + N (사실상 이런 것이 N+1 문제) 으로 나갈 수 있는 SQL 쿼리의 수를
1 : 1 로 줄여주니 좋은 것이다!!
N+1관련한 fetch join 과 문제 해결 방법은 아래에 다른 포스팅을 첨부한다
https://codinggyun.tistory.com/101
'Spring > JPA' 카테고리의 다른 글
[JPA] Entity가 아닌 DTO로 DB에서 data 가져오기 (0) | 2022.03.10 |
---|---|
[JPA] 1:N / N:1 상황에서의 N+1 문제 해결 (Fetch Join ~ 지연로딩/Batch Size) (0) | 2022.03.09 |
[JPA] 준영속 엔티티를 변경하는 방법 - 변경 감지 / 병합(Merge) (0) | 2022.02.15 |
Spring Boot Repository EntityManager / EntityManagerFactory 엔티티매니저 / 엔티티매니저팩토리 (0) | 2021.12.27 |
[JPA] JPA 세팅 및 MySQL 8 아마존 RDS 연결하기 by Spring Boot (0) | 2021.09.10 |