Blog Hoch
Mar 2026·2 tup leghDe'wI' chenmoHta'

N+1 Query Qagh 'ej chay' Qotlh

#sql#databases#performance

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).

chu'Rate Limiting Algorithms: Token Bucket vs Sliding WindowqanGit Rebase vs Merge: nuq lo'