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 문제는
지연 로딩과 프록시로 인해
연관 엔티티 접근 시점마다 쿼리가 실행되면서 발생하는 문제다.
'IT > Backend' 카테고리의 다른 글
| [TDD 시리즈 2/2] Spring에서 TDD로 코딩해보기 – 포인트 사용 도메인 예제 (0) | 2026.01.06 |
|---|---|
| [Spring] AntPathMatcher 정리 – URL 패턴 매칭 방식과 사용 시점 (2026 업데이트) (0) | 2026.01.05 |
| [TDD 시리즈 1/2] TDD란 무엇인가, 개념, 특징, 장단점, 면접 질문 정리 (0) | 2026.01.05 |
| [멱등성 시리즈 2/2] 멱등성 (Idempotency) 면접 대비 정리 (질문 유형 · 답변 한 줄 요약) (0) | 2026.01.03 |
| [멱등성 시리즈 1/2] 멱등성(Idempotency)이란? HTTP API에서 왜 중요한가 (0) | 2026.01.02 |