Laravel load() and loadMissing()
In Laravel, Eloquent ORM provides two methods for loading relationships between models — Eager loading and Lazy loading.
Lazy loading.
The relationship data is “lazy loaded” when accessing Eloquent relationships as properties. This means the relationship data is not actually loaded until you first access the property.
But this approach introduces the N+1 problem that many know in Laravel, for example from laravel documentation:
use App\Models\Book;
$books = Book::all();
foreach ($books as $book) {
echo $book->author->name;
}
This loop will execute one query to retrieve all of the books, then another query for each book to retrieve the book’s author.
So, we have 1 Query for the book list + N queries for author data per each book hence N+1.
But Laravel is gracious enough to give us some helpers to avoid such performance pitfalls.
Eager loading.
This can happen before the usage of any relation properties.
We can use eager loading to load relation data before we access them, thus reducing the number of queries from N+1 to just 2.
Through the usage of with()
you can "eager load" relationships at the time you query the parent model:
$books = Book::with('author')->get();
1 to retrieve the book list and 1 to retrieve all authors for all books and we can do that by:
$books = Book::with('author')->get();
foreach ($books as $book) {
echo $book->author->name;
}
Lazy Eager loading
Sometimes you want to eager load relations after the parent model has already been retrieved, or only if a condition is met.
In Laravel, load()
and loadMissing()
are two methods available on Eloquent ORM that are used to eagerly load relationships.
$book->load('author');
Which also might be used in a way to only eager load missing ones:
$book->loadMissing('author');
Contrary to the load()
method, loadMissing()
method filters through the given relations and lazily "eager" loads them only if not already loaded.
This method can be useful when you want to load only the relationships that have not been loaded yet, to avoid unnecessary database queries. For example, to load all the missing comments for the same post, you can use loadMissing()
method like this:
$post = Post::find(1);
$post->loadMissing('comments');
This will load only the comments that have not been loaded yet, without making additional queries for the comments that have already been loaded.
Through accepting closures, both methods support custom relation loading logic.
In terms of performance, loadMissing()
method is generally faster than load()
method, because it only loads the missing relationships, without making additional queries for the relationships that have already been loaded. This can significantly reduce the number of database queries and improve the overall performance of your application.
In summary, load()
loads all the relationships specified, even if they have already been loaded, while loadMissing()
loads only the relationships that have not been loaded yet.