성능n+1prisma
Prisma N+1, include가 만능이 아닌 이유
✨ AI 요약
- Prisma는 N+1 문제를 완전히 해결하지 못하며, 주의가 필요하다. - include 사용 시 루프 안에서 개별 쿼리를 호출하면 N+1이 발생한다. - 과도한 include와 직렬 await 사용은 성능 저하를 초래할 수 있다.
조회 45
ORM을 쓰면 N+1은 피할 수 없는 주제다. Prisma는 기본기가 좋은 편이지만, 그래서 오히려 방심하다 당한다.
Prisma의 기본 방어선
const posts = await prisma.post.findMany({
include: { author: true, tags: { include: { tag: true } } },
});
include는 내부적으로 관계별 배치 쿼리로 풀린다. posts 1번 + authors 1번 + tags 1번. 루프 안에서 findUnique를 부르는 고전적 N+1은 include만 써도 사라진다.
함정 1 — 루프 안의 개별 쿼리
// 이러면 도로 N+1
for (const post of posts) {
const count = await prisma.comment.count({ where: { postId: post.id } });
}
집계는 include에 _count로 태우자.
include: { _count: { select: { comments: true, likes: true } } }
함정 2 — 과도한 include
include는 관계 테이블의 전 컬럼을 다 가져온다. 카드 목록에 본문(content)까지 실려 오는 식이다. 목록 화면은 select로 필요한 필드만 고르는 게 맞다. 우리 피드 API는 select 전환만으로 응답 크기가 70% 줄었다.
함정 3 — 직렬 await
// 순차 — 총 지연 = 합
const user = await getUser();
const posts = await getPosts();
// 병렬 — 총 지연 = 최대값
const [user2, posts2] = await Promise.all([(), ()]);