使用相同类型的多个关系改进预加载
Improve eager loading with multiple relationships of the same type
我有以下型号:
class Message extends Model
{
public function sender(): HasOne
{
return $this->hasOne(User::class, 'sender_id', 'id');
}
public function receiver(): HasOne
{
return $this->hasOne(User::class, 'receiver_id', 'id');
}
}
当我执行 Message::with(['sender', 'receiver'])->all()
时,预先加载会执行以下查询:
SELECT * FROM messages
SELECT * FROM users IN(1, 3, 5)
SELECT * FROM users IN(3, 5, 7)
那是几乎可能的冗余最少的方法。但它仍然加载用户 3 和用户 5 两次。有没有办法使用 eloquent 和预先加载来进一步改进它?
不,不是真的。
您提供的示例是一个例外,没有任何迹象表明发送者和接收者查询中都会出现任何用户。
您可以编写一些代码来更改 Eloquent 在这种情况下的行为方式,但这不值得。
缺点:
- 案例仅限于在同一实体上急切加载的两个或多个关系。
- 您需要将删除的结果附加到第二个查询中,并使用正确的 Order 它应该在其中。
- 与从数据库中保存的代码相比,代码的性能成本可能更高。
试试这些
首先替换你的foreignKey
和localKey
。
class 消息扩展模型
{
public function sender(): HasOne
{
return $this->hasOne(User::class, 'sender_id', 'id');
}
public function receiver(): HasOne
{
return $this->hasOne(User::class, 'receiver_id', 'id');
}
}
然后使用这个模型查询
return Message::query()->with(['sender', 'receiver'])->get()
我有以下型号:
class Message extends Model
{
public function sender(): HasOne
{
return $this->hasOne(User::class, 'sender_id', 'id');
}
public function receiver(): HasOne
{
return $this->hasOne(User::class, 'receiver_id', 'id');
}
}
当我执行 Message::with(['sender', 'receiver'])->all()
时,预先加载会执行以下查询:
SELECT * FROM messages
SELECT * FROM users IN(1, 3, 5)
SELECT * FROM users IN(3, 5, 7)
那是几乎可能的冗余最少的方法。但它仍然加载用户 3 和用户 5 两次。有没有办法使用 eloquent 和预先加载来进一步改进它?
不,不是真的。
您提供的示例是一个例外,没有任何迹象表明发送者和接收者查询中都会出现任何用户。
您可以编写一些代码来更改 Eloquent 在这种情况下的行为方式,但这不值得。
缺点:
- 案例仅限于在同一实体上急切加载的两个或多个关系。
- 您需要将删除的结果附加到第二个查询中,并使用正确的 Order 它应该在其中。
- 与从数据库中保存的代码相比,代码的性能成本可能更高。
试试这些
首先替换你的foreignKey
和localKey
。
class 消息扩展模型
{
public function sender(): HasOne
{
return $this->hasOne(User::class, 'sender_id', 'id');
}
public function receiver(): HasOne
{
return $this->hasOne(User::class, 'receiver_id', 'id');
}
}
然后使用这个模型查询
return Message::query()->with(['sender', 'receiver'])->get()