[ JPA에서 @BatchSize 사용 시 장점 ]
@BatchSize 어노테이션은 Hibernate에서 성능을 개선하는 데 유용하다.
특히 대량의 데이터를 처리할 때 이 어노테이션의 효과를 직접 느낄 수 있다.
상황
cust_info (사용자 정보) 테이블을 조회할 때,
대부분의 상황에서 cust_agree_info (사용자 동의 정보)도 함께 조회해야 해야 하는 상황.
예를들어 1,000명의 회원 정보를 한꺼번에 조회 할 때는 어떨까?
- JPA 기본 쿼리 방식
- 기본적으로 Hibernate는 1000명의 cust_info를 조회한 후,
- 각 회원의 cust_agree_info를 조회하기 위해 별도의 쿼리를 실행함.
- 결과적으로 1000개의 쿼리가 데이터베이스로 나가게 되며,
- 이로 인해 성능 저하를 초래하는 N+1 문제가 발생함.
- 기본적으로 Hibernate는 1000명의 cust_info를 조회한 후,
- @BatchSize 적용 후
- Hibernate는 여러 개의 cust_agree_info를 배치로 로딩하여 단일 쿼리로 조회할 수 있음.
- 예를 들어 @BatchSize(size = 1000)으로 설정하면,
- Hibernate는 cust_seq 값을 기준으로 IN 절을 사용하여
- 1000개의 cust_agree_info를 한 번의 쿼리로 가져옴.
- 이렇게 하면 쿼리 수가 크게 줄어들어 성능이 개선됨.
[ @BatchSize(size = 1000) 사용 했을 때 ]
- 쿼리가 1번 나감
[ @BatchSize(size = 1000) 사용 안 했을 때 ]
- 쿼리가 데이터숫자대로 나감 (여기서는 4개)
[ JPA에서 Fetch Join 사용 시 장점 ]
Fetch Join을 사용하면 연관된 엔티티를 단일 쿼리로 함께 로딩할 수 있어 성능이 개선됨.
이를 통해 N+1 문제를 방지하고 데이터베이스 쿼리 수를 줄일 수 있음
그럼 언제 FetchJoin을 쓰고 언제 @BatchSize를 써야할까?
- FetchJoin을 사용할 때
- 쿼리에서 연관된 모든 데이터를 즉시 로딩해야 하는 경우에 유용함
- 간단한 연관 관계에서 연관된 엔티티를 함께 로딩해야 할 때
- 연관된 엔티티가 상대적으로 적거나 적절히 필터링된 경우
- @BatchSize를 사용할 때
- 연관된 엔티티가 많은 경우.
- FetchJoin으로 즉시 로딩되지 않는 엔티티들에 대해 BatchSize가 효과적일 수 있음
👉 FetchJoin을 무조건 사용할 수 없는 이유 중 하나가
JOIN FETCH를 사용하여 여러 연관된 엔티티를 로딩할 때
OneToMany 컬렉션이 여러 개 있을 경우 주의가 필요하다.
특히, 한 쿼리에서 JOIN FETCH로 OneToMany 컬렉션을 두 개 이상 조인하려고 하면
MultipleBagFetchException 같은 예외가 발생할 수 있다.
오히려 여러 OneToMany 연관관계를 JOIN FETCH로 동시에 로딩하려는 경우,
쿼리가 비효율적이거나 예외가 발생할 수 있다.
이러한 경우에는 지연 로딩(FetchType.LAZY)과 @BatchSize를 활용하거나
쿼리를 분할하는 방법을 고려하는 것이 좋다.
JPA에서 N+1 문제를 해결하고 성능을 최적화할 때
FetchJoin과 @BatchSize를 적절히 조합해서 사용하는게 좋다.
기본적으로 FetchType.LAZY와 @BatchSize를 사용하고,
필요에 따라 특정 쿼리에서 JOIN FETCH를 사용하여 성능을 최적화한다.
예를 들어, 특정 조회에서 JOIN FETCH를 사용하여 관련 데이터를 한 번에 가져오고,
그 외의 경우에는 @BatchSize를 사용하여 성능을 개선하는 방식.
'Programming > Java & Spring 관련 내용 정리' 카테고리의 다른 글
Push Server "개선" 작업을 해보다. (1) | 2024.08.27 |
---|---|
MDC를 활용해 쓰레드 전환을 이해해보다. (4) | 2024.08.27 |
[Java] 인터페이스를 통해 if문의 향연을 고쳐보았다. (0) | 2023.09.11 |
[Java] 역직렬화로 JSON 포맷을 바꿔보았다. (0) | 2023.08.21 |
[Java] 인터페이스 사용하여 필터링 기능을 구현해 보았다. (0) | 2023.08.11 |