目标
列表接口每行发一次数据库查询,随列表增长延迟成倍上升。本配方把单条查询包装为按请求创建的 DataLoader,把同一时刻的多次加载合并为一次批量查询并按 id 回填结果,随后通过查询日志确认从 N 次降为 1 次;提醒 DataLoader 必须按请求创建以防缓存串用户。
步骤要点
- 把单条查询包装为按请求创建的 DataLoader。
- 用查询日志确认查询次数从 N 降为 1。
- 按请求创建新的 loader 防止缓存串用户。
- 限制批量大小避免超大 IN 子句。
const userLoader = new DataLoader(async (ids) => {
const rows = await db.query('SELECT * FROM users WHERE id = ANY($1)', [ids]);
const byId = new Map(rows.map(r => [r.id, r]));
return ids.map(id => byId.get(id) || null);
});
排错提示
- 缓存跨请求会串数据,必须按请求创建。
- 批量过大可能超出查询限制。
- 每请求缓存只在单次请求内去重。
适用边界
- 需要支持批处理的数据访问。
- 大批量需限制。