✅ N+1 문제란?

졸용·2025년 4월 20일

✅ N+1 문제란?

N+1 문제JPA (또는 ORM) 사용 시 자주 발생하는 성능 이슈 중 하나이다.

→ 어떤 1개의 쿼리(1)N개의 결과를 가져온 다음, 각 결과마다 추가로 1개씩 쿼리(N)가 실행되어 총 N+1개의 쿼리가 발생하는 문제를 말한다.


📌 예시로 이해하기

예를 들어, 게시판에서 게시글과 작성자 정보를 조회한다고 가정해보면,

List<Post> posts = postRepository.findAll(); // 1번 쿼리
for (Post post : posts) {
    System.out.println(post.getUser().getName()); // N번 쿼리 (작성자 정보를 매번 가져옴)
}
  • postRepository.findAll() → 게시글 10개를 가져옴 → 1개의 쿼리

  • post.getUser().getName() → 매 게시글마다 사용자 정보 조회 → 10개의 쿼리

👉 결국 총 1 + 10 = 11번의 쿼리가 실행된다. 게시글이 100개면 101개 쿼리...


💥 왜 문제일까?

  • 성능 저하: 쿼리 수가 급격히 증가하면 DB에 부하가 크다

  • 불필요한 반복 쿼리: 대부분의 경우 한 번에 데이터를 가져올 수 있다



✅ 해결 방법

1️⃣ Fetch Join 사용

@Query("SELECT p FROM Post p JOIN FETCH p.user")
List<Post> findAllWithUser();
  • JOIN FETCH를 사용하면 게시글과 작성자 정보를 한 번에 조회한다

  • N+1 문제를 방지할 수 있다


2️⃣ Entity Graph

@EntityGraph(attributePaths = {"user"})
List<Post> findAll();
  • 간단히 설정으로 fetch join처럼 작동하게 해준다

3️⃣ LAZY → EAGER로 변경 (권장 ❌)

  • 연관관계를 EAGER로 바꾸면 항상 로딩되긴 하지만, 예기치 않게 불필요한 데이터까지 다 가져오는 부작용이 생길 수 있어 잘 쓰지 않는다


🧠 정리

용어의미
N+1 문제1번의 쿼리 후, N개의 추가 쿼리가 실행되는 성능 문제
주 원인연관된 엔티티를 LAZY 로딩하면서 루프에서 참조할 때
해결 방법fetch join, EntityGraph, 또는 DTO로 필요한 것만 조회


📍 메서드명을 바꾼 이유

결론부터 말하자면,

✅ 결론

방식장점메서드 이름
@Query + JOIN FETCH기능 명확히 드러남findAllWithUser()
@EntityGraph관심사 분리 / 깔끔함findAll() (이름 단순화)

❗👉 이름을 findAll()로 바꾼 건 어노테이션이 책임을 대신 지기 때문!


Fetch Join을 사용한 쿼리문과

@Query("SELECT p FROM Post p JOIN FETCH p.user")
List<Post> findAllWithUser();

@EntityGraph 어노테이션을 사용한 쿼리문

@EntityGraph(attributePaths = {"user"})
List<Post> findAll();

을 비교했을 때 메서드명을 findAllWithUser 에서 findAll 로 바꾼 이유는

  • 장점

    • 코드가 간결해지고

    • @EntityGraph에 의해 관심사는 분리된다.

    • "이 메서드는 어떤 데이터를 가져오는가?"
      → 메서드 시그니처

    • "어떤 연관 엔티티를 같이 가져오는가?"
      → 어노테이션


⚠️ 단, 상황에 따라 다르다!

  • 팀에서 정책적으로 쿼리 성격을 메서드명에 명시하고 싶다면 findAllWithUser()도 전혀 문제 없다

  • 다만, @EntityGraphJPA가 알아서 내부 쿼리를 바꿔주기 때문에,
    보통은 이름을 간단하게 유지하는 쪽을 더 많이 선택한다


@EntityGraph쿼리를 바꾸는 역할은 하되, 메서드 이름에는 영향을 주지 않기 때문이다
즉, 쿼리의 동작은 변경되지만, 메서드 이름은 꼭 바꿀 필요가 없다.

profile
꾸준한 공부만이 답이다

0개의 댓글