Files
gh-djankies-claude-configs-…/skills/optimizing-query-performance/references/index-strategy.md
2025-11-29 18:22:25 +08:00

1.9 KiB

Index Strategy Guide

When to Add Indexes

Add @@index for fields that are:

  • Frequently used in where clauses
  • Used for sorting (orderBy)
  • Foreign keys with frequent joins
  • Composite conditions used together

Single-Field Indexes

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  createdAt DateTime @default(now())
  status    String

  @@index([createdAt])
  @@index([status])
}

Use Case:

await prisma.user.findMany({
  where: { status: 'active' },
  orderBy: { createdAt: 'desc' },
  take: 20
})

Both status filter and createdAt sort benefit from indexes.

Composite Indexes

model Order {
  id         Int      @id @default(autoincrement())
  userId     Int
  status     String
  createdAt  DateTime @default(now())
  totalCents Int

  user User @relation(fields: [userId], references: [id])

  @@index([userId, status])
  @@index([status, createdAt])
}

Composite Index Rules:

  1. Order matters: [userId, status] helps queries filtering by userId, or userId + status
  2. Does NOT help queries filtering only by status
  3. Most selective field should come first
  4. Match your most common query patterns

Use Case:

await prisma.order.findMany({
  where: {
    userId: 123,
    status: 'pending'
  },
  orderBy: { createdAt: 'desc' }
})

First index [userId, status] optimizes the where clause. Second index [status, createdAt] would help if querying by status alone with date sorting.

Index Trade-offs

Benefits:

  • Faster read queries (10-100x improvement on large tables)
  • Required for efficient sorting and filtering
  • Essential for foreign key performance

Costs:

  • Slower writes (insert/update/delete must update indexes)
  • Storage overhead (5-20% per index)
  • Diminishing returns beyond 5-7 indexes per table

Rule: Only index fields actually used in queries. Remove unused indexes.