PHP
Optimizing Database Performance with Eloquent Eager Loading and Constraints
Boost application performance by using Laravel Eloquent eager loading to prevent N+1 queries. Learn to conditionally load related models only when specific criteria are met, reducing unnecessary database load.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function posts()
{
return $this->hasMany(Post::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
class Post extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
}
// Basic Eager Loading to prevent N+1 problem:
// $users = User::with('posts')->get();
// foreach ($users as $user) {
// echo $user->name; // User query (1 query)
// foreach ($user->posts as $post) {
// echo $post->title; // Posts query (1 query for all users' posts)
// }
// }
// Eager Loading multiple relationships:
// $posts = Post::with(['user', 'comments'])->get();
// Eager Loading with specific constraints on the related model:
// Retrieve users along with their published posts only
// $usersWithPublishedPosts = User::with(['posts' => function ($query) {
// $query->where('published', true);
// }])->get();
// Eager Loading nested relationships:
// $postsWithUsersAndTheirComments = Post::with('user.comments')->get();
// Conditionally Eager Loading (Laravel 7+):
// Load comments only if the post has more than 5 comments
// $posts = Post::withCount('comments')->get(); // Get the count first
// $posts->loadWhen($posts->where('comments_count', '>', 5)->pluck('id'), 'comments'); // Load only for relevant posts
// More common conditional eager loading is using `when` or `whenLoaded` in view/transformer
// Example: User::when($shouldLoadPosts, function ($query) { $query->with('posts'); })->get();
How it works: Eager loading is a crucial optimization technique in Eloquent to combat the N+1 query problem, where iterating over a collection of models and accessing a relationship for each model generates a new query for every iteration. Using the `with()` method, Eloquent fetches all related models in one or two separate queries. This snippet demonstrates basic eager loading for `User`s `posts`, loading multiple relationships, applying constraints to eager-loaded relationships (e.g., `published` posts), and loading nested relationships. It also touches upon conditional eager loading, allowing you to load relationships based on specific conditions, further optimizing performance by only fetching necessary data.