패치 조인에 대해서는 어느 정도는? 알고 있었고 이번 프로젝트에서도 적용했는데, 그런데도 발생하는 N + 1 처럼 보이는 문제에 대해서는 어떻게 대응해야 될 지 공부하던 중 배치 사이즈에 대해서 알게 됐다.
이걸 적용하면 어느 정도 해결될 것 같다.
Hibernate의 @BatchSize 애노테이션을 사용하여 한 번에 여러 개의 연관 엔티티를 가져오도록 설정할 수 있다.
@BatchSize(size = 10)
private List<Menu> menus;
Java
복사
이렇게 하면 N번의 쿼리가 N/10번으로 줄어들어 성능이 개선될 수 있다.
해당 옵션은 정확히 N+1 문제를 해결하는 방법은 아니고 N+1 문제가 발생하더라도 1+1 와 같이 한 번만 더 조회하는 방식으로 작동한다.
select * from menu where shop_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
SQL
복사
이렇게 size만큼 in 절로 쿼리가 나간다.
위와 같이 컬럼에 옵션을 줄수도 있고 application.yml 설정 파일에 적용할 수도 있다.
spring:
jpa:
properties:
hibernate:
default_batch_fetch_size: 1000
Java
복사
대부분의 DB IN 절의 최대 개수 값이 1000이라 1000으로 설정한다고 한다.