1.9 KiB
1.9 KiB
N+1 Prevention Guide
Anti-Patterns
Over-fetching
Problem:
const user = await prisma.user.findUnique({
where: { id },
include: {
posts: {
include: {
comments: {
include: {
author: true,
},
},
},
},
},
})
Issue: Fetches thousands of records, massive data transfer
Fix: Use select with limits
const user = await prisma.user.findUnique({
where: { id },
select: {
id: true,
name: true,
posts: {
select: {
id: true,
title: true,
_count: {
select: {
comments: true,
},
},
},
take: 10,
orderBy: {
createdAt: 'desc',
},
},
},
})
Inconsistent Selection
Problem:
const posts = await prisma.post.findMany({
include: {
author: true,
},
})
Issue: Full author object when only name needed
Fix: Select specific fields
const posts = await prisma.post.findMany({
select: {
id: true,
title: true,
author: {
select: {
name: true,
},
},
},
})
Selecting Then Filtering
Problem:
const users = await prisma.user.findMany()
const activeUsers = users.filter(u => u.status === 'active')
Issue: Fetches all users, filters in application
Fix: Filter in database
const activeUsers = await prisma.user.findMany({
where: { status: 'active' },
select: {
id: true,
name: true,
email: true,
},
})
Prevention Strategies
- Always load relations upfront - Never query in loops
- Use select with relations - Don't fetch unnecessary fields
- Add take limits - Prevent accidental bulk loads
- Use _count - Don't load relations just to count
- Test with realistic data - N+1 only shows at scale