ormlazy-loadingjoin-fetch
N+1 query 문제를 설명해 주세요
- 예상 시간
- 6분
30초 답변
꼬리질문
조금 더 깊게 물어본다면
답변 뒤에 이어질 수 있는 질문들을 하나씩 열어볼 수 있어요.
N+1 문제는 lazy loading 때문에만 생기나요?
fetch join을 쓰면 항상 해결되나요?
batch loading은 어떤 방식인가요?
N+1 문제를 어떻게 발견하나요?
projection은 왜 도움이 되나요?
부가 설명
처음에는 코드가 단순해 보여서 문제를 놓치기 쉽습니다. posts.map(post => post.author.name)처럼 자연스러운 코드가 내부에서는 게시글 목록 조회 1번과 작성자 조회 N번으로 바뀔 수 있습니다. 데이터가 5개일 때는 티가 안 나지만, 500개가 되면 DB와 네트워크 왕복 비용이 바로 병목이 됩니다.
해결책은 필요한 데이터를 어느 시점에 한 번에 가져올지 명확히 정하는 것입니다. 화면에 작성자 이름이 반드시 필요하면 join fetch나 projection으로 처음부터 가져오고, 여러 연관을 한꺼번에 당겨오면 row 폭발이 생길 수 있으니 batch size도 선택지가 됩니다. 문제의 원인은 ORM 자체가 아니라 로딩 전략과 조회 범위를 통제하지 않을 때 숨어 있는 쿼리가 늘어난다는 데 있습니다.
한 줄 정리
N+1은 한 번이면 될 조회가 데이터 개수만큼 숨어서 반복되는 문제입니다.