1.6 KiB
1.6 KiB
title, type, tags, last_updated
| title | type | tags | last_updated | |||||
|---|---|---|---|---|---|---|---|---|
| N+1 Query Prevention | concept |
|
2026-05-01 |
N+1 Query Prevention
Definition
N+1 查询问题是指应用程序在获取一组主对象后,对每个对象分别发起一次额外查询来获取关联数据的反模式。假设获取 N 个用户,每个用户查一次帖子,总共产生 1 + N 次数据库往返。
The Problem
// ❌ Bad: N+1 pattern
const users = await db.query("SELECT * FROM users LIMIT 10");
for (const user of users) {
user.posts = await db.query(
"SELECT * FROM posts WHERE user_id = $1",
[user.id]
);
}
// 1 + 10 = 11 queries
The Solution
// ✅ Good: Single query with aggregation
const usersWithPosts = await db.query(`
SELECT
u.id, u.email, u.name,
COALESCE(
json_agg(
json_build_object('id', p.id, 'title', p.title)
) FILTER (WHERE p.id IS NOT NULL),
'[]'
) as posts
FROM users u
LEFT JOIN posts p ON p.user_id = u.id
GROUP BY u.id
LIMIT 10
`);
// 1 query
Key Techniques
- JOIN + json_agg:PostgreSQL 下用
json_agg聚合嵌套关联数据 - 批量查询(Batch Loading):拆分为 2-3 次查询(IN 子句分批)
- 预加载(Eager Loading):ORM 的
include/preload机制 - 物化视图:对稳定结构做预计算
Source
Connections
- QueryPlanAnalysis — 通过 EXPLAIN ANALYZE 识别 N+1
- engineering-backend-architect — 架构设计时需避免 N+1
- engineering-sre — N+1 是生产环境性能问题的常见根源