【发布时间】:2021-07-16 22:47:32
【问题描述】:
我对旧的 N+1 问题有点意见。我正在运行 Lighthouse 4.8、Laravel 5.8,并在我的配置中将 batched_queries 和 batchload_relations 设置为 true。我在我的架构中设置了 hasMany 和 hasOne(匿名了一点):
type Team {
id: Int!
Y_resource_id: Int
X_resource_id: Int
name: String
description: String
start_date: Date
cost: Float
Y: Resource @hasOne
X: Resource @hasOne
members(
where: _ @whereConditions
hasDepartmentMember: _ @whereHasConditions(columns: ["z_id","start_date"])
orderBy: [OrderByClause!] @orderBy
): [TeamMember] @hasMany @is_logged_in
options: [TeamResourceOption] @hasMany
optionIds: [Int!]
}
我正在使用多个利用这些关系的访问器函数,以及一些自定义解析器和本地范围。这些似乎是导致 N+1 问题的原因,例如,当我在 Team 中加载时,有 N+1 问题的 php 查询之一是这个(在 Team 模型上尝试加载加入并填充信息):
public function getHasTeamLeaderAttribute(): bool
{
return $this->members()->teamLeaders()->count() > 0;
}
这是 members() 函数:
public function members(): HasMany
{
return $this->hasMany(TeamMember::class);
}
以及 TeamMember 类:
public function scopeTeamLeaders($query)
{
return $query->where('team_members.group_role', '=', TeamMember::ROLE_TEAM_LEADER);
}
Clockwork 将其显示为 2 N+1 个问题(我调用了两次):
N+1 queries: App\Models\Teams\Team::App\Models\Teams\TeamMember loaded 4 times.
Team.php:254
N+1 queries: App\Models\Teams\Team::App\Models\Teams\TeamMember loaded 2 times.
Team.php:254
我尝试在访问器中使用 loadMissing 来加载 teamLeaders 但这似乎增加了 N+1 查询,我还尝试使用 $with 我需要的关系加载模型,但这会使整个应用程序变慢(我假设是因为它现在会在不需要的地方自动加载它)。
这是一个继承的项目,我对 GraphQL 并不完全熟悉,所以任何指向正确方向的指针都会很棒。谢谢!
【问题讨论】:
标签: laravel laravel-5 optimization graphql-js laravel-lighthouse