Spring 기초 정리 - N+1 문제

Zyoon·2025년 6월 9일

Spring 기초정리

목록 보기
12/18
post-thumbnail

📘 N+1 문제와 해결방법 알아보기


N + 1 문제란?

  • 만약 당신이 도시락 배달을 하는 사람이고, 1층부터 10층까지 아파트에 도시락을 배달해야 한다.
  • 여기서 N + 1 문제
    1. 우선 10층까지 모든 집 주소만 받는다. (1번)
    2. 그 다음에 각 집에 일일이 가서 음식 종류를 물어본다. (10번)
    3. 이렇게 해서 총 1 + 10 = 11번 움직인다.
  • 이것이 바로 N+1 문제이다. 이렇게 할 경우 필요 이상으로 움직여야 하고, 집이 100개, 1000개로 늘어나면 시간적으로 체력적으로 손해가 심해진다.
  • 그렇기 때문에 처음 집 주소를 받을 때, 음식 정보도 같이 받는 방법으로 해결하는 것이 필요이상의 손해를 줄일 수 있는것이다.

N + 1 코드 예시

Entity

//getter, setter 생략
@Entity
public class Post {
    @Id @GeneratedValue
    private Long id;

    private String title;

    @ManyToOne(fetch = FetchType.LAZY) // 지연로딩이 핵심
    private User author;
}

@Entity
public class User {
    @Id @GeneratedValue
    private Long id;

    private String name;
}

문제 발생 코드

public void showPosts() {
    List<Post> posts = postRepository.findAll(); // 1번 쿼리

    for (Post post : posts) {
		    // N번 쿼리
        System.out.println(post.getTitle() + " - " + post.getAuthor().getName());
    }
}
  • findAll() 로 게시글을 가져온다. (1번)
  • getAuthor().getName() 실행 때마다 작성자 정보가 DB 에서 따로 조회된다. (N번)

해결 방법

Fetch Join

@Query("SELECT p FROM Post p JOIN FETCH p.author")
List<Post> findAllWithAuthor();
  • JPQL 안에서 Join Fetch 를 직접 작성한다.
  • 내부적으로 SQL JOIN 을 실행한다.
  • 쿼리를 직접 작성하기 때문에 복잡해질 수 있지만, 그만큼 자유롭게 작성이 가능하다.

EntityGraph

@EntityGraph(attributePaths = "author")
List<Post> findAll();
  • 어노테이션으로 연관 엔티티를 설정해서 자동으로 Fetch Join 하게 만든다.
  • 내부적으로도 JOIN 을 실행하지만 자동 처리된다.
  • 코드가 깔끔하고 유지보수가 쉽지만, 조건이 많거나 복잡한 쿼리는 어렵다.
profile
기어 올라가는 백엔드 개발

0개의 댓글