N+1 쿼리 문제는 왜 발생하며 어떻게 해결할 수 있나요?
답변 포인트
목록을 한 번 조회한 뒤 각 항목마다 연관 데이터를 다시 조회하는 상황을 생각해보세요.
정답 및 해설
빠른 요약
N+1 문제는 처음 N개의 데이터를 조회한 뒤, 각 데이터의 연관 정보를 가져오려고 N번의 추가 쿼리가 발생하는 문제입니다. 예를 들어 게시글 목록 20개를 조회한 후 각 게시글의 작성자를 개별 조회하면 총 1 + 20번의 쿼리가 실행됩니다.
N+1 문제는 처음 N개의 데이터를 조회한 뒤, 각 데이터의 연관 정보를 가져오려고 N번의 추가 쿼리가 발생하는 문제입니다. 예를 들어 게시글 목록 20개를 조회한 후 각 게시글의 작성자를 개별 조회하면 총 1 + 20번의 쿼리가 실행됩니다.
개발 중에는 데이터가 적어 티가 나지 않지만, 운영 데이터가 늘면 응답 시간이 급격히 나빠지고 DB 부하가 커집니다. ORM에서 lazy loading을 사용할 때 특히 자주 발생합니다.
해결 방법은 상황에 따라 다릅니다.
- Join fetch 또는 eager loading으로 필요한 연관 데이터를 한 번에 가져오기
- batch loading으로 여러 id를 모아
WHERE IN (...)쿼리 실행 - GraphQL에서는 DataLoader 패턴 사용
- 화면에 정말 필요한 데이터만 DTO/projection으로 조회
하지만 무조건 join이 답은 아닙니다. join으로 중복 row가 폭증하거나 pagination이 꼬일 수 있습니다. 목록 화면에서는 필요한 필드만 projection하고, 상세 화면에서는 더 풍부한 연관 데이터를 가져오는 식으로 읽기 모델을 나누는 편이 안정적입니다.
핵심은 쿼리 개수를 관찰하는 습관입니다. 로그, APM, query count 테스트로 N+1을 조기에 발견하는 것이 중요합니다.