IT/Backend

JPA N+1 문제란? 왜 발생하는지부터 실제 면접 답변 정리까지

바다, 2026. 1. 12. 14:28
반응형

JPA N+1 문제란? 왜 발생하는지부터 실제 면접에서 받은 질문에 대한 정리

JPA를 사용했다면
한 번쯤은 반드시 듣게 되는 질문이 있다.

“N+1 문제가 뭔가요?”
“왜 발생하죠?”

이 질문은
단순히 해결 방법을 아는지를 묻는 질문이 아니다.

면접관은 이 질문을 통해
ORM을 얼마나 깊이 이해하고 있는지를 본다.

이 글은

  • N+1이 무엇인지
  • 왜 발생하는지
  • JPA에서 쿼리가 언제 실행되는지
  • 실제 면접에서 받은 질문
  • 면접에서 바로 써먹을 수 있는 답변 정리
    를 중심으로 정리한다.

1. N+1 문제가 뭔가요? (한 문장 정의)

N+1 문제란
연관된 엔티티를 조회할 때
초기 쿼리 1번 + 연관 엔티티 조회 쿼리 N번이 추가로 실행되는 문제이다.


2. 면접관이 N+1을 묻는 이유

면접관이 이 질문으로 확인하는 것은 다음과 같다.

  • ORM을 얼마나 이해하는가
  • 객체 그래프와 SQL 실행 흐름을 이해하는가
  • 쿼리가 언제 실행되는지를 아는가
  • 성능 문제가 왜 발생하는지 설명할 수 있는가

즉,
“해결책을 외웠는지”가 아니라
동작 원리를 이해하는지를 보는 질문이다.


3. N+1은 왜 발생하는가

핵심 원인은 다음 세 가지다.

1) 지연 로딩(Lazy Loading)

JPA에서 연관관계는 기본적으로 지연 로딩이다.

@ManyToOne(fetch = FetchType.LAZY)
private Team team;

이 설정의 의미는
연관 엔티티를 즉시 가져오지 않고, 필요할 때 조회한다는 것이다.


2) 프록시 객체(Proxy)

지연 로딩 상태에서는
연관 엔티티가 실제 객체가 아니라 프록시 객체로 존재한다.

즉,

  • 처음에는 쿼리가 실행되지 않는다
  • 프록시 객체의 필드에 접근하는 순간
  • 실제 SQL이 실행된다

3) 쿼리 실행 시점에 대한 오해

많은 개발자가
“조회 메서드를 호출하면 쿼리가 실행된다”고 생각한다.

하지만 JPA에서는 다르다.

쿼리는 ‘접근하는 순간’ 실행된다.

이 시점 이해가 없으면
N+1 문제를 근본적으로 이해하기 어렵다.


4. JPA에서 쿼리는 언제 실행되는가

정리하면 다음과 같다.

  • JPQL 실행 → 기본 엔티티 조회 쿼리 실행 (1번)
  • 연관 엔티티는 프록시 상태
  • 반복문 등에서 연관 엔티티 접근
  • 접근할 때마다 쿼리 실행 (N번)

그래서 결과적으로
1 + N 쿼리 구조가 된다.


5. N+1이 실제로 발생하는 예시 (중요)

면접에서는 이런 질문을 자주 받는다.

“말로 말고, 실제로 어떤 상황에서 N+1이 발생하나요?”

예시 상황

  • 회원(Member)과 팀(Team)이 연관관계
  • 회원은 여러 명, 각 회원은 하나의 팀에 소속
@Entity
public class Member {
    @Id
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Team team;
}

회원 목록 조회 코드

List<Member> members = memberRepository.findAll();

이 시점에서는
회원 목록을 조회하는 쿼리 1번만 실행된다.

select * from member;

문제는 여기서 발생한다

for (Member member : members) {
    System.out.println(member.getTeam().getName());
}

이 코드가 실행되면:

  • 첫 번째 member → team 조회 쿼리 실행
  • 두 번째 member → team 조회 쿼리 실행
  • 회원 수만큼 team 조회 쿼리 실행

결과적으로:

  • 회원 조회 쿼리 1번
  • 팀 조회 쿼리 N번

👉 이게 바로 N+1 문제다.


6. 실제 면접에서 받은 질문 예시

실제로 면접에서 받았던 질문은 이런 식이었다.

“N+1 문제는 왜 발생하나요?”
“실제 코드 기준으로 설명해보세요.”
“fetch join으로 무조건 해결되나요?”

이 질문들은 전부
동작 원리 이해 여부를 묻는 질문이다.


7. 면접 답변용 정리 (바로 써먹기)

Q. N+1 문제가 뭔가요?

JPA에서 연관관계를 조회할 때
지연 로딩으로 인해 초기 쿼리 1번 이후
연관 엔티티 접근 시마다 추가 쿼리가 실행되는 문제입니다.

 


Q. 왜 발생하나요?

연관 엔티티가 지연 로딩으로 프록시 상태에 있고,
프록시 객체에 접근하는 시점에 쿼리가 실행되기 때문에 발생합니다.

 


Q. 실제로 어떤 상황에서 발생하나요?

예를 들어 회원 목록을 조회한 뒤
반복문에서 각 회원의 팀 정보를 접근하면
회원 조회 1번 이후 팀 조회 쿼리가 회원 수만큼 추가로 실행됩니다.

 


Q. 쿼리는 언제 실행되나요?

조회 메서드 호출 시점이 아니라
프록시 객체의 필드에 접근하는 순간 실행됩니다.

 


8. 실무에서는 어떻게 판단하나

실무에서는
“무조건 N+1을 없애야 한다”는 접근은 위험하다.

판단 기준은 다음과 같다.

  • 실제로 성능 이슈가 발생하는가
  • 조회 데이터 양이 얼마나 되는가
  • 한 번에 가져오는 것이 더 효율적인가

즉,

문제가 되는 경우에만 해결한다
쿼리 흐름을 보고 판단한다

 


9. 정리

N+1 문제는
단순한 JPA 이슈가 아니다.

  • ORM 이해도
  • 객체 그래프 이해
  • SQL 실행 시점 이해
  • 성능 사고 방식

을 한 번에 확인할 수 있는
아주 좋은 면접 질문이다.

이 질문에
“fetch join 쓰면 됩니다”로 끝나지 않고
왜 발생하는지, 언제 발생하는지, 예시로 설명할 수 있다면
충분히 좋은 답변이다.

 


한 줄 요약

N+1 문제는
지연 로딩과 프록시로 인해
연관 엔티티 접근 시점마다 쿼리가 실행되면서 발생하는 문제다.

 

반응형