Postgres 'Partial Index'를 Prisma에서 사용하는 방법

인한별
인한별
조회 수143

PostgreSQL 부분 인덱스(Partial Index)란?

PostgreSQL의 부분 인덱스는 테이블의 전체 데이터가 아닌, 특정 조건(WHERE 절)을 만족하는 데이터의 하위 집합에 대해서만 생성되는 인덱스입니다.


주요 장점

  • 인덱스 크기 감소: 조건에 맞는 데이터만 인덱싱하므로 디스크 저장 공간과 메모리(RAM)를 크게 절약할 수 있습니다.
  • 성능 향상: 인덱스의 크기가 작아져 검색(Read) 속도가 빨라집니다. 또한, 조건에 해당하지 않는 데이터를 삽입하거나 수정할 때는 인덱스를 업데이트할 필요가 없기 때문에 쓰기(Write) 성능의 오버헤드도 줄어듭니다.
  • 부분적 고유성(Partial Uniqueness) 보장: 전체 테이블이 아닌 특정 상태의 레코드들 사이에서만 유니크 제약 조건을 걸 수 있습니다.


대표적인 활용 사례

  • Soft-delete 처리: deleted_at IS NULL 조건으로 삭제되지 않은 활성 데이터만 인덱싱하여 조회 성능을 높이고 싶을 때.
  • 상태 기반 고유성 검증: 탈퇴한 회원의 이메일은 중복 가입을 허용하지만, 현재 status = 'active'인 회원들 사이에서는 이메일이 중복되지 않도록 제약할 때.


Prisma 7.4에서 부분 인덱스 사용하기

최근 릴리즈된 Prisma ORM 7.4 버전부터 partialIndexes 기능이 프리뷰로 도입되었습니다. 이제 복잡한 Custom Migration을 작성할 필요 없이, Prisma 스키마 레벨에서 직접 부분 인덱스를 매우 쉽게 정의할 수 있습니다.


1. 프리뷰 기능 활성화

먼저 schema.prisma 파일의 generator 블록에 partialIndexes 프리뷰 기능을 명시적으로 추가해야 합니다.

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["partialIndexes"]
}


2. 부분 인덱스 정의 구문

Prisma 7.4에서는 @@index, @@unique, @unique 속성에 새롭게 where 인자가 추가되었습니다. 프로젝트의 상황과 조건의 복잡도에 따라 두 가지 구문 중 하나를 선택해 작성할 수 있습니다.


A. Raw SQL 구문 (Raw SQL Syntax)

데이터베이스에 종속적인 복잡한 조건문이나 함수를 그대로 사용해야 할 때 유용합니다. raw() 함수를 이용해 SQL 표현식을 직접 작성합니다.

model User {
  id        Int       @id @default(autoincrement())
  email     String
  status    String
  deletedAt DateTime?

  // 활성 사용자 간에만 이메일 고유성 보장
  @@unique([email], where: raw("status = 'active'"))
  
  // 삭제되지 않은 데이터만 인덱싱하여 조회 성능 최적화
  @@index([email], where: raw("\"deletedAt\" IS NULL"))
}


B. 타입 세이프 객체 구문 (Type-safe Object Syntax)

비교적 단순한 조건이라면, Prisma 특유의 강력한 타입 시스템을 활용해 객체 형태로 안전하고 직관적이게 작성할 수 있습니다.

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  published Boolean @default(false)

  // 출간된 게시물만 인덱싱
  @@index([title], where: { published: true })
  
  // 출간된 상태의 게시물 제목 고유성 보장 (부정 연산자 사용 예시)
  @@unique([title], where: { published: { not: false } })
}

댓글 0

댓글은 회원만 작성할 수 있습니다.

로그인하고 댓글 달기
댓글을 불러오는 중입니다...