--- title: "N+1 Query Prevention" type: concept tags: [database, performance, n+1, postgresql, query-optimization] last_updated: 2026-05-01 --- # N+1 Query Prevention ## Definition N+1 查询问题是指应用程序在获取一组主对象后,对每个对象分别发起一次额外查询来获取关联数据的反模式。假设获取 N 个用户,每个用户查一次帖子,总共产生 1 + N 次数据库往返。 ## The Problem ```typescript // ❌ 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 ```typescript // ✅ 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 - [[engineering-database-optimizer]] ## Connections - [[QueryPlanAnalysis]] — 通过 EXPLAIN ANALYZE 识别 N+1 - [[engineering-backend-architect]] — 架构设计时需避免 N+1 - [[engineering-sre]] — N+1 是生产环境性能问题的常见根源