As asked
A page loads in 4 seconds. The database shows 200 queries per page load. You suspect an ORM N+1. Walk me through how you would fix it.
Sample answer outline
Confirm the diagnosis: turn on query logging, look at the call site that generates the chatty queries. Usually a loop that accesses a lazy-loaded relation. Fix with the ORM's eager loading primitive (include, with, populate, prefetch_related). Alternatively, batch the lookup with a single IN query. After the fix, verify the page is one or two queries. Watch for the second-order N+1 where the eagerly loaded set itself has a lazy relation. For React/Node: use a dataloader to batch requests inside a request scope.
Reference implementation (typescript)
// Bad: N+1 (one query per post for its author)
const posts = await prisma.post.findMany({ where: { feed: feedId } });
for (const post of posts) {
const author = await prisma.user.findUnique({ where: { id: post.authorId } });
// ...
}
// Good: eager load in a single query
const posts = await prisma.post.findMany({
where: { feed: feedId },
include: { author: true },
});
// Alternative: batch with DataLoader inside a request scope
const userLoader = new DataLoader<string, User>(async (ids) => {
const users = await prisma.user.findMany({ where: { id: { in: [...ids] } } });
const byId = new Map(users.map((u) => [u.id, u]));
return ids.map((id) => byId.get(id)!);
});Expect these follow-ups
- Why does an ORM lazy-load by default?
- When is a JOIN slower than two queries?
- How would you catch an N+1 in CI before it ships?