首页 > 解决方案 > 在 http 请求的各个部分共享 pg-promise 任务

问题描述

我在 GraphQL 应用程序中使用pg-promise,并且由于解析器的嵌套/迭代性质,每个 HTTP 请求都会进行大量数据库查询。

所以我想知道当解析器正在收集数据时,是否有一种更有效的方法来共享连接池中的连接?

我知道pg-promise任务仅在函数回调时才有效,并且我看不到任何其他方式来链接查询(如此所述)。

例子

GraphQL 查询:

{
  users {
    files {
      name
      date
    }
  }
}

使用Apollo 服务器时的解析器示例

Query: {
    users: (obj, args, context, info) => {
      return context.db.manyOrNone('select id from users')
    }
 }

Users: {
  files: (obj, args, context, info) => {
    const userId = obj.id;
    return context.db.manyOrNone('select * from files where user_id = $1', userId);
  }
}

例如,如果有很多用户,这将生成大量 SQL 查询。

笔记

我知道dataloader解决诸如 N+1 Select 之类的问题的技术,但目前我无法重新架构此应用程序,而仅仅提高数据库连接的效率将是一个巨大的性能提升。

谢谢你。

标签: node.jsgraphqlapollo-serverpg-promise

解决方案


池中的每个 HTTP 端点和每个数据库连接都是异步的。

如果您尝试跨多个 HTTP 端点重用相同的数据库连接,那么每当它们需要访问数据库时,它们就会相互阻塞,这是不好的。

如果池中的连接数少于访问数据库的 HTTP 端点数,那么您的 HTTP 服务的可扩展性很差。您需要至少与 HTTP 端点的连接数相匹配。

因此,您正在寻找的 - 跨多个 HTTP 端点共享数据库连接是一个坏主意。

如果您想在单个 HTTP 请求中对多个数据解析器进行分组,您可以在单个任务中统一处理逻辑(请参阅任务)。

还有手动连接,通过方法connect,但我不建议将它用于一般连接重用,因为它适用于特定情况,否则容易出错并使自动连接的想法无效。


推荐阅读