N+1 Query Qagh 'ej chay' Qotlh
page 50 blog posts 'ej author pong list development Daq (test rows Dach) nom, production Daq Qaw' - query slow pagh, wa' query pagh. 51 queries: wa' posts tlhap, post Hoch wa' author tlhap. N+1 Qagh ghaH. ORM apps Daq performance bug law': ORM Qaw' (invisible).
chay' tu'lu'
const posts = await Post.findAll(); // 1 query
for (const post of posts) {
post.author = await User.findByPk(post.authorId); // N queries, one per post
}
pagh Qagh legh pagh - readable, obvious, 5 test posts ms Daq Qu'. production 5,000 posts: 5,001 database round trips. round trip latency dominate. 2ms/round trip 10 seconds (network wait), wa' query wa' round trip Daq nob laH.
spot
signature: query count result set size rap law'. ORM frameworks query log laH - page suspect Daq on, count. 10 items = 11 queries; 100 items = 101 queries vaj N+1.
// Sequelize example: log every query for the duration of one request
const posts = await Post.findAll({ logging: console.log });
SELECT * FROM users WHERE id = ? shape row Hoch repeat (parameter neH choH) - tell.
fix: eager loading
related data same query pagh wa' batched follow-up query Daq load (row Hoch query pagh).
Join-based eager loading, ORM built-in relationship loading:
// Sequelize
const posts = await Post.findAll({ include: User }); // 1 query, joined
// Prisma
const posts = await prisma.post.findMany({ include: { author: true } });
// Django ORM
posts = Post.objects.select_related('author')
wa' query JOIN rap, author data post row Hoch attach.
Batched loading, join Dun pagh (row counts multiply):
// 2 queries total, not N+1
const posts = await Post.findAll();
const authorIds = [...new Set(posts.map((p) => p.authorId))];
const authors = await User.findAll({ where: { id: authorIds } });
const authorsById = new Map(authors.map((a) => [a.id, a]));
for (const post of posts) {
post.author = authorsById.get(post.authorId);
}
wa' query posts, wa' query author Hoch (Set dedupe), application memory Daq join. cha' round trips (10 pagh 10,000 posts).
raw SQL, same idea
ORM pagh vaj eager-loading equivalent: join SoH ghItlh (loop query pagh):
-- N+1: one query per post, issued from application code in a loop
SELECT * FROM posts;
SELECT * FROM users WHERE id = ?; -- repeated per post
-- one query
SELECT posts.*, users.name AS author_name
FROM posts
JOIN users ON users.id = posts.author_id;
N+1 ORM Qagh pagh - ORM loop-and-query pattern accident ghItlh Dun (post.author normal property access legh, query hide).
nested case: N+1 level Dung
another relationship level Dung vaj compound - post Hoch comments:
const posts = await Post.findAll({ include: User }); // fixed the first N+1
for (const post of posts) {
post.comments = await Comment.findAll({ where: { postId: post.id } }); // reintroduced it
}
author lookup fix comments post loop Daq fetch vaj Qotlh pagh. nested relationships same eager load:
const posts = await Post.findAll({ include: [User, Comment] });
Hoch eager load Qagh
inverse mistake: relationship Hoch query Hoch eager load "just in case" - data law' tlhap, cheap single-table lookup six-table join choH. fix "reH eager load" pagh - code path lo' Hoch load. includes per-query explicit.
yaj
N+1 queries code review 'ej small dev dataset Daq invisible. production-scale data query count bottleneck vaj Qagh. realistic data Daq real query logs legh (test rows correctness neH pagh). loop iteration Hoch query vaj eager loading (join pagh batched follow-up).