N+1 문제란? #56
Replies: 4 comments
-
|
N+1 문제는 연관관계가 있는 엔티티를 조회할 때, 예를 들어 예약 목록을 한 번에 조회했는데, 각 예약의 회원 정보를 사용할 때마다 회원 조회 쿼리가 예약 개수만큼 추가로 나가는 상황이 있습니다. N+1 문제는 단순히 쿼리가 많이 나가는 문제가 아니라, |
Beta Was this translation helpful? Give feedback.
-
N+1이란N+1 이란 JPA ORM을 사용할 때, 발생하는 문제로써, 객체 모델과 관계형 모델의 불일치로 인해서 발생하는 구조적인 문제점이다. N+1이 왜 발생할까방탈출 미션으로 예를 들어보자면 예시를 통한 문제 상황 설명자세히 예를 들어서 어떤 문제인지 설명하겠습니다. 예약 목록 조회하는 쿼리 1번 이 이렇게 있습니다. SELECT * FROM reservation그 예약 목록이 10건이라면 reservation.getTheme().getName() 시에 예약 수만큼 10번이 또 이렇게 발생하게 됩니다. SELECT * FROM theme WHERE id = ?합치면 1+10 = 11번 쿼리가 발생합니다. 왜 문제가 될까?1. 데이터가 늘어날수록 쿼리가 선형적으로 폭발한다.데이터가 늘어남에 따라서 확장적으로 문제가 점점 커지게 된다. 2. 불필요한 네트워크 왕복 비용 발생1번의 쿼리로 끝낼 수 있는 문제를 불필요한 DB와의 네트워크 왕복을 처리하게 된다. 3. 불필요한 커넥션 풀 점유요청 하나가 쿼리 3,001를 소모하게 된다면 DB 커넥션 하나를 그 시간 내내 점유하게 된다. |
Beta Was this translation helpful? Give feedback.
-
|
N+1문제는 부모 리소스 조회 이후, 연관된 데이터 개수(N)만큼 추가 쿼리가 발생하는 문제입니다. 대표적으로 JPA가 연관 데이터를 조회하는 과정에서 발생합니다. 이 문제의 원인을 지연로딩이나 즉시로딩의 차이로 오해하는 경우가 많은데, 근본적으로는 JPA가 연관 엔티티를 조회하는 방식 때문에 발생하는 문제입니다. (이는 조금더 깊게 들어가면, 결국 디비 테이블과 객체의 패러다임 불일치를 해결하기 위해 JPA가 선택한 조회 방식의 부수적인 부작용 중 하나라고 이해하면 좋을 것 같습니다.) 구체적으로 기본적으로 JPA는 객체그래프를 탐색할 때 연관객체를 한번에 조인해서 가져올 판단을 하지 않습니다. 그렇기에 연관 객체가 사용될 때 이에 대응하는 Select 쿼리를 날려 연관데이터를 불러옵니다. 즉시로딩의 경우에도, 내부적으로 부모 리소스에 대한 쿼리(1)과 연관 객체 조회 쿼리(N)가 정책에 의해 한번에 실행됩니다. 그렇기에 즉시로딩 자체가 N+1을 해결해 주지는 못합니다. 결국 JPA의 설계자들은 자동으로 JOIN을 하는 선택지를 포기하고, 필요할때 조회하는 방식을 선택한 것인데 이 내부 철학은 무엇을 함께 조회할지는 개발자가 직접 선택하도록 판단을 내린 것으로 보입니다. |
Beta Was this translation helpful? Give feedback.
-
|
그래서, JPA의 지연로딩 시, List 개수만큼 추가 데이터를 조회하는 쿼리가 발생하여 N+1이 발생합니다. 이를 해결하기 위해서는 FetchJoin, EntityGraph, Batch를 사용하는데, 결국 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
N+1 문제란 무엇이고 왜 발생하나요?
Beta Was this translation helpful? Give feedback.
All reactions