【发布时间】:2021-08-27 20:37:52
【问题描述】:
Keystone.js 似乎没有提供“N+1”问题的解决方案。 也许,它们是一些插件?
【问题讨论】:
标签: query-optimization keystonejs
Keystone.js 似乎没有提供“N+1”问题的解决方案。 也许,它们是一些插件?
【问题讨论】:
标签: query-optimization keystonejs
你可以试试看https://www.keystonejs.com/guides/cache-hints/
这是解决此问题的典型模式。
你可以试试:
const app = new GraphQLApp({
apollo: {
cacheControl: {
defaultMaxAge: 3600,
},
},
});
缓存所有解析器结果。
【讨论】:
你是哪个版本的?当前版本的 KeystoneJS (Keystone Next) 是在 Prisma 之上构建的,它应该构建相当高性能的数据库查询。如果您正在执行的特定 GraphQL 查询导致 SQL 不理想,则它可能代表 Keystone 或 Prisma 代码中的错误,在这种情况下,如果您能隔离问题并log an issue,那就太好了。
如果您要添加查询数据库的挂钩、访问控制或虚拟字段,则可能会遇到 N+1 问题,因为可以为查询中返回的每个项目调用这些函数。例如,这段代码取自virtual-fields example,如果按原样使用,会导致 N+1 次查询:
Post: list({
fields: {
// [... various fields ...]
author: relationship({ ref: 'Author.posts', many: false }),
// A virtual field which uses `item` and `context` to query data.
authorName: virtual({
field: schema.field({
type: schema.String,
async resolve(item, args, context) {
const { author } = await context.lists.Post.findOne({
where: { id: item.id },
query: 'author { name }',
});
return author && author.name;
},
}),
}),
},
}),
这里,authorName 字段的解析器函数将为每个加载的项目调用(假设该字段被查询)。在这些情况下,我建议在 Keystone CRUD API 的顶部使用类似 GraphQL dataloader (或类似)的东西。如果使用正确,dataloader 可以组合多个查询并解决 N+1 行为。
【讨论】: