【问题标题】:How to improve performance on nested graphql connections when using pagination使用分页时如何提高嵌套 graphql 连接的性能
【发布时间】:2020-05-31 07:57:27
【问题描述】:

我正在尝试实施某种基本的社交网络项目。它有 PostsCommentsLikes 和其他任何东西一样。

  • 一个帖子可以有多个 cmets
  • 一个帖子可以有很多赞
  • 一篇文章可以有一个作者

我在客户端应用程序上有一个/posts 路由。它通过分页列出Posts 并显示它们的titleimageauthorNamecommentCountlikesCount

graphql 查询是这样的;

query {
  posts(first: 10, after: "123456") {
    totalCount
    edges {
      node {
        id
        title
        imageUrl
        author {
          id
          username
        }
        comments {
          totalCount
        }
        likes {
          totalCount
        }
      }
    }
  }
}

我正在使用apollo-serverTypeORMPostgreSQLdataloader。我使用dataloader 获取每个帖子的author。我只是将请求的authorIdsdataloader 批处理,从PostgreSQL 获取authorswhere user.id in authorIds 查询,将查询结果映射到每个authorId。要知道,dataloader最基本的用法。

但是当我尝试查询每个post 下的commentslikes 连接时,我卡住了。如果没有分页,我可以使用相同的技术并为他们使用postId。但是现在我必须包含分页的过滤器参数。对于某些where 条件,可能还有其他过滤器参数。

我找到了数据加载器的cacheKeyFn 选项。我只是为传递给数据加载器的过滤器对象创建一个字符串键,它不会复制它们。它只是将唯一的传递给batchFn。但是我无法使用TypeORM 创建一个sql 查询来分别获取每个firstafterorderBy 参数的结果并将结果映射回调用数据加载器的函数。

我搜索了spectrum.chat 源代码,我认为它们不允许用户查询嵌套连接。还尝试了 Github GraphQL Explorer,它可以让您查询嵌套连接。

有没有推荐的方法来实现这一点?我了解如何将object 传递给dataloader 并使用cacheKeyFn 对它们进行批处理,但我无法弄清楚如何在一个查询中从PostgreSQL 获取结果并将结果映射为从加载程序返回。

谢谢!

【问题讨论】:

标签: postgresql graphql apollo typeorm dataloader


【解决方案1】:

所以,如果你稍微限制一下,这是可行的。限制是只允许结果第一页上的批处理连接,例如因此,您并行获取的所有连接都是通过参数完成的。这是一个合理的约束,因为它允许您执行诸如获取前 10 个提要项和每个项的前 3 个 cmets 之类的操作,这代表了一个相当典型的用例。尝试在单个查询中支持独立分页不太可能满足 UI 的任何实际用例,因此它可能是过度优化。考虑到这一点,您可以使用 PostgreSQL 使用窗口来支持“为每个父级获取前 N 个子级”用例。

这有点繁琐,但有一些答案可以让你找到正确的方向:Grouped LIMIT in PostgreSQL: show the first N rows for each group?

所以使用 dateloader 和 cacheKeyFn 一样,让你的 loader 函数识别你是否可以执行优化(例如 after is null 并且所有其他参数都相同)。如果可以优化,请使用窗口查询,否则像往常一样并行执行未优化的查询。

【讨论】:

  • 感谢您的回答!我实际上已经通过使用 UNION ALL 尝试了一些东西,它似乎对我有用。我已经能够使用不相关的参数获取不同类型的分页结果,并将它们映射回数据加载器的“调用者”。每个新的嵌套连接级别只有 1 个 DB 命中。我认为这对于 GraphQL 的观点来说是相当不错的。现在有点冗长,我不确定它是否能 100% 工作。我将进行更多实验并分享我的发现。再次感谢!
  • 啊,是的,联合查询可以工作,但请确保检查不同方法的性能。
猜你喜欢
  • 2022-10-24
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多