简体   繁体   中英

Improve eager loading with multiple relationships of the same type

I have the following model:

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');
    }
}

When I do Message::with(['sender', 'receiver'])->all() , eager loading executes the following queries:

SELECT * FROM messages
SELECT * FROM users IN(1, 3, 5)
SELECT * FROM users IN(3, 5, 7)

That's almost the least redundant way possbile. But it still loads user 3 and user five two times. Is there a way to further improve this using eloquent and eager loading?

No, not really.

The example you provided is an exception, nothing tells that any user will be present in both sender and receiver queries.

You could write some code to change how Eloquent behaves in those case but it's not worth it.

CONS:

  • The case is restricted to two or more relation eager loaded on the same entity.
  • You need to attach the results you removed back to the second query with the right Order it should be in.
  • might cost way more performance in the code than what it saves from the database.

Try these

First replace your foreignKey and localKey .

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');
    }
}

And then use this model query

return Message::query()->with(['sender', 'receiver'])->get()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM