【问题标题】:How to solve "N+1" problem in Keystone.js如何解决 Keystone.js 中的“N+1”问题
【发布时间】:2021-08-27 20:37:52
【问题描述】:

Keystone.js 似乎没有提供“N+1”问题的解决方案。 也许,它们是一些插件?

【问题讨论】:

    标签: query-optimization keystonejs


    【解决方案1】:

    你可以试试看https://www.keystonejs.com/guides/cache-hints/

    这是解决此问题的典型模式。

    你可以试试:

    const app = new GraphQLApp({
      apollo: {
        cacheControl: {
          defaultMaxAge: 3600,
        },
      },
    });
    

    缓存所有解析器结果。

    【讨论】:

      【解决方案2】:

      你是哪个版本的?当前版本的 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 行为。

      【讨论】:

        猜你喜欢
        • 2011-02-05
        • 2020-08-21
        • 2021-01-22
        • 2019-01-18
        • 2015-02-12
        • 1970-01-01
        • 2021-12-10
        • 2021-04-26
        • 1970-01-01
        相关资源
        最近更新 更多