使用相同类型的多个关系改进预加载

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 它应该在其中。
  • 与从数据库中保存的代码相比,代码的性能成本可能更高。

试试这些

首先替换你的foreignKeylocalKey

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()