Skip to content
Advertisement

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?

Advertisement

Answer

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.
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement