금요일

Prisma N+1 쿼리 문제 완벽 해결

 🔍 검색 키워드: Prisma N+1 쿼리, include relation, select 최적화, Prisma 성능 튜닝, 데이터베이스 쿼리 최적화


Prisma N+1 쿼리 문제 완벽 해결


증상: 데이터 조회 시 데이터베이스 쿼리가 너무 많다

사용자 목록 조회 후 각 사용자의 프로필을 가져오려니 쿼리가 100개 이상 날아가나요?


1. 사용자 목록 조회 (1개 쿼리)

2. 각 사용자의 프로필 조회 (N개 쿼리)

결과: 1 + N = 101개 쿼리!


이것이 N+1 쿼리 문제입니다. 성능 저하, 데이터베이스 부하 증가를 초래합니다.


원인 분석


원인 1: 관계 데이터를 include/select 없이 조회

const users = await prisma.user.findMany();

for (const user of users) {

  const profile = await prisma.profile.findUnique({

    where: { userId: user.id }

  });

}

결과: 1 + N개 쿼리


원인 2: 중첩 관계에서 include 누락

const posts = await prisma.post.findMany();

for (const post of posts) {

  const author = await prisma.user.findUnique({

    where: { id: post.authorId }

  });

  const comments = await prisma.comment.findMany({

    where: { postId: post.id }

  });

}

결과: 1 + N + N*M개 쿼리


해결 방법


✅ 방법 1: include로 관계 데이터 포함 (기본)

const users = await prisma.user.findMany({

  include: {

    profile: true

  }

});

1개 쿼리로 완료!


✅ 방법 2: select로 필요한 컬럼만 선택 (최적화)

const users = await prisma.user.findMany({

  select: {

    id: true,

    email: true,

    profile: {

      select: {

        bio: true,

        avatar: true

      }

    }

  }

});

데이터양 감소, 성능 향상


✅ 방법 3: where 조건으로 불필요한 데이터 필터링

const post = await prisma.post.findUnique({

  where: { id: 1 },

  include: {

    comments: {

      where: { approved: true },

      orderBy: { createdAt: 'desc' },

      take: 10

    }

  }

});

효율적!


결론

- include로 관계 데이터 포함 — N+1의 기본 해결

- select로 필요한 필드만 — 성능 + 보안

- where로 DB 수준 필터링 — 불필요한 데이터 전송 방지

- 중첩은 2단계까지 — 복잡도와 성능의 균형

- 쿼리 로깅으로 검증 — 개발 중 문제 조기 발견


Prisma는 ORM이지만, SQL 수준의 최적화 의식을 가져야 효율적인 쿼리를 만들 수 있습니다.

댓글 없음:

댓글 쓰기