GraphQL DataLoader批量加载与N+1问题
请解释GraphQL中的N+1查询问题,并用DataLoader(Node.js)实现批量加载和缓存来解决此问题。
回答
孤独的心
N+1问题:posts查询返回N条,每条post查询author触发N次查询,共N+1次。
DataLoader解决方案:
const DataLoader = require('dataloader');
const batchUsers = async (ids) => {
const users = await db.user.findAll({ where: { id: ids } });
return ids.map(id => users.find(u => u.id === id) || null);
};
const userLoader = new DataLoader(batchUsers);
const resolvers = {
Post: {
author: (parent, args, context) => context.userLoader.load(parent.authorId)
}
};
原理:同一事件循环内收集所有load()调用,下一tick批量查询,结果按输入顺序映射返回,请求级别缓存避免重复查询。
优化效果:N+1→2次查询,数据库IO从O(N)降到O(1)。