[JPA] n+1 문제 해결

이다혜·2023년 12월 14일

n + 1 문제란?

orm을 사용하는 애플리케이션에서 자주 발생하는 성능 이슈 중 하나로
데이터베이스에서 엔티티를 검색할 때 해당 엔티티와 관계를 맺은 다른 엔티티들을 함께 가져오지 않고, 그 후에 각 엔티티에 대한 추가 쿼리를 실행하는 경우에 발생한다.

예제

	@DisplayName("게시물 별 댓글 수 출력")
    @Test
    void t() {
        List<Article> articles = articleService.findAll();
        
        articles.forEach(article -> {
            System.out.println("게시물 번호 : " + article.getId());
            System.out.println("댓글 수 : " + article.getComments().size());
        });
    }

위의 테스트 코드를 실행하면 게시물을 가져오기 위해 1 번의 쿼리가 발생하고

SELECT * FROM articles;

댓글을 가져오기 위해 N번의 추가 쿼리가 발생한다.

SELECT * FROM article_comment WHERE article_id = 1;
SELECT * FROM article_comment WHERE article_id = 2;
...
SELECT * FROM article_comment WHERE article_id = N;

때문에 N+1 문제가 발생한다.

Default Batch Fetch Size로 해결 방법

Hibernate의 'default_batch_fetch_size' 속성을 사용하여 해결할 수 있다.
이 속성은 연관된 엔티티의 컬렉션을 가져올 때 일괄 쿼리를 사용하여 데이터를 가져오는 방식을 지정한다.

application.yml

spring:
  jpa:
    properties:
      hibernate:
        default_batch_fetch_size: 20

위의 설정처럼 size를 20으로 설정하면 1번 게시글의 댓글을 조회할 때 20개의 게시글에 대한 댓글을 조회하여 성능을 향상시킬 수 있다.

0개의 댓글