Day 52 · 5/5
🌿 중급 DB

데이터베이스 N+1 문제

쉽게 이해하기

반 학생 30명의 성적표를 출력한다고 해보세요. 학생 명단을 한 번에 가져온 뒤, 각 학생마다 개별적으로 성적을 조회하면 총 31번(명단 1번 + 학생별 30번)의 요청이 필요합니다. 하지만 명단과 성적을 한 번에 요청하면 1번으로 끝나죠. 이것이 N+1 문제와 해결 방법의 차이입니다.

핵심 정리

연관된 데이터를 조회할 때 쿼리가 불필요하게 여러 번 실행되는 성능 문제입니다.

자세히 알아보기

N+1 문제는 ORM을 사용할 때 자주 발생하는 성능 이슈입니다. 예를 들어 게시글 10개를 조회한 뒤, 각 게시글의 작성자를 가져올 때 총 11번(게시글 1번 + 작성자 10번)의 쿼리가 실행됩니다. 데이터가 많아질수록 쿼리 횟수가 기하급수적으로 늘어나서 서버가 느려집니다. 해결 방법은 '미리 로딩(Eager Loading)'입니다. 첫 쿼리에서 연관 데이터를 한 번에 가져오는 것이죠. Prisma에서는 include 옵션, Drizzle에서는 with 구문, Django에서는 select_related()나 prefetch_related()를 사용합니다. 이렇게 하면 쿼리가 1~2번으로 줄어듭니다. 실무에서는 개발자 도구나 데이터베이스 로그를 보면서 N+1 문제를 찾습니다. 페이지 로딩이 느린데 쿼리가 수십 번 실행되고 있다면 N+1 문제일 가능성이 높습니다. 특히 리스트 페이지나 피드 화면처럼 여러 항목을 보여주는 곳에서 자주 발생합니다. N+1 문제는 ORM의 편리함 뒤에 숨은 함정입니다. ORM이 자동으로 쿼리를 생성해주지만, 어떻게 작동하는지 이해하지 못하면 성능 문제를 놓치기 쉽습니다. 실무에서는 데이터베이스 쿼리 로그를 항상 확인하는 습관이 중요합니다.