1.9 KiB
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:
- Order matters: [userId, status] helps queries filtering by userId, or userId + status
- Does NOT help queries filtering only by status
- Most selective field should come first
- 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.