【问题标题】:GraphQL one to many performance issue and limitationGraphQL 一对多性能问题和限制
【发布时间】:2021-04-02 04:16:33
【问题描述】:

我有一个带有 2 个表的数据库 => 玩家(10k 条目)和目标(100k 条目)。我在他们之间有一对多的关系(玩家有很多目标)

@Entity()
@ObjectType()
class Player {
  @Field(() => ID)
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @Field(() => [Goal])
  @OneToMany(
    () => Goal,
    goal => goal.player
  )
  goals: Goal[];
  ...
}

@Entity()
@ObjectType()
class Goal {
  @Field(() => ID)
  @PrimaryGeneratedColumn("uuid")
  id: string;

  @ManyToOne(
    () => Player,
    player => player.id
  )
  player: Player;
  ...
}

我想查询玩家及其目标,以便在我的客户端应用中显示玩家排名

query scorers{
  players{
    id
    totalGoals
  }
}

播放器解析器如下所示

@Resolver(Player)
class PlayerResolver {
  @Query(() => [Player])
  async players() {
    return this.playerRepository.createQueryBuilder("player").getMany();
  }
  @FieldResolver()
  async totalGoals(@Root() player: Player) {
    return this.goalRepository.count({ player });
  }
}

这并不高效,因为它在后台创建了一个 SQL 查询来请求每个玩家的目标。所以它可能是 10k 查询。这是最好的策略吗?另外我想知道我怎么可能按进球数来排序球员。 我正在使用type-graphqltypeorm

【问题讨论】:

  • 将 totalGoals 缓存为播放器中的字段/道具,不应依赖 [reading] 解析器...更新目标 instert
  • 一次查询 10k 玩家似乎是 imo 的实际问题。
  • @xadm 在 SQL 数据库中创建缓存字段/prop 是否常见?你对此有参考吗?
  • 它经常使用且成本高昂...您如何按总进球数对球员进行排序...在一个赛季中?复杂性呈指数级增长

标签: javascript typescript graphql typeorm typegraphql


【解决方案1】:

您可以尝试提前使用连接构建查询(在查询解析器级别,使用 @Info 读取请求的字段)或使用 DataLoader 库来批处理查询并解决 N + 1 问题。

【讨论】:

    猜你喜欢
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 2013-11-26
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多