모든 블로그 포스트
개발 노하우2023-08-20 (일요일)

Prisma 고급 쿼리 최적화 기법

최디비8분 읽기
Prisma 고급 쿼리 최적화 기법

Prisma 고급 쿼리 최적화 기법

Prisma는 Node.js와 TypeScript를 위한 ORM(Object-Relational Mapping) 도구로, 타입 안전성과 직관적인 API를 제공합니다. 이 글에서는 Prisma에서 복잡한 쿼리를 작성하고 최적화하는 고급 기법을 알아봅니다.

관계 쿼리 최적화

1. 선택적 관계 포함하기

include 옵션을 사용하여 필요한 관계만 선택적으로, 필요한 필드만 로드할 수 있습니다:

// 모든 필드를 포함한 관계 쿼리
const userWithPosts = await prisma.user.findUnique({
  where: { id: userId },
  include: { posts: true }
});

// 선택적 필드만 포함한 최적화된 쿼리
const optimizedUser = await prisma.user.findUnique({
  where: { id: userId },
  include: {
    posts: {
      select: {
        id: true,
        title: true,
        createdAt: true
      }
    }
  }
});

2. 중첩 관계 처리

중첩된 관계를 효율적으로 쿼리하는 방법:

const userWithPostsAndComments = await prisma.user.findUnique({
  where: { id: userId },
  include: {
    posts: {
      include: {
        comments: {
          select: {
            id: true,
            content: true,
            author: {
              select: { name: true }
            }
          }
        }
      }
    }
  }
});

쿼리 성능 향상 기법

1. 페이지네이션 적용하기

커서 기반 페이지네이션은 대용량 데이터 처리에 효율적입니다:

// 오프셋 기반 페이지네이션
const postsPage = await prisma.post.findMany({
  skip: 10,
  take: 10,
});

// 커서 기반 페이지네이션 (권장)
const postsCursor = await prisma.post.findMany({
  take: 10,
  cursor: { id: lastPostId },
  orderBy: { id: 'asc' },
});

2. 집계 함수 사용하기

const postStats = await prisma.post.aggregate({
  _count: { id: true },  // 총 게시물 수
  _avg: { viewCount: true },  // 평균 조회수
  _max: { viewCount: true },  // 최대 조회수
  where: { 
    published: true,
    author: { id: authorId }
  }
});

3. 트랜잭션 활용하기

const [newPost, updatedUser] = await prisma.$transaction([
  prisma.post.create({
    data: {
      title: 'New Post',
      content: 'Content...',
      authorId: userId
    }
  }),
  prisma.user.update({
    where: { id: userId },
    data: { postCount: { increment: 1 } }
  })
]);

고급 필터링 및 정렬

1. 복잡한 필터 조건

const filteredPosts = await prisma.post.findMany({
  where: {
    AND: [
      { published: true },
      {
        OR: [
          { title: { contains: searchTerm, mode: 'insensitive' } },
          { content: { contains: searchTerm, mode: 'insensitive' } }
        ]
      },
      {
        authorId: {
          in: followingIds
        }
      }
    ]
  },
  orderBy: [
    { createdAt: 'desc' },
    { viewCount: 'desc' }
  ]
});