[ PROMPT_NODE_25104 ]
data-n-plus-one
[ SKILL_DOCUMENTATION ]
## 通过批量加载消除 N+1 查询
N+1 查询是指在循环中为每个项目执行一次查询。应使用数组或 JOIN 将其合并为单个查询。
**错误做法 (N+1 查询):**
sql
-- 第一次查询:获取所有用户
select id from users where active = true; -- 返回 100 个 ID
-- 然后是 N 次查询,每个用户一次
select * from orders where user_id = 1;
select * from orders where user_id = 2;
select * from orders where user_id = 3;
-- ... 还有 97 次查询!
-- 总计:101 次数据库往返
**正确做法 (单次批量查询):**
sql
-- 收集 ID 并使用 ANY 进行一次查询
select * from orders where user_id = any(array[1, 2, 3, ...]);
-- 或者使用 JOIN 代替循环
select u.id, u.name, o.*
from users u
left join orders o on o.user_id = u.id
where u.active = true;
-- 总计:1 次往返
应用模式:
sql
-- 不要在应用程序代码中循环:
-- for user in users: db.query("SELECT * FROM orders WHERE user_id = $1", user.id)
-- 传递数组参数:
select * from orders where user_id = any($1::bigint[]);
-- 应用程序传递:[1, 2, 3, 4, 5, ...]
参考:[N+1 查询问题](https://supabase.com/docs/guides/database/query-optimization)