PHP
Optimizing Eloquent Queries with Eager Loading Specific Columns and Nested Relationships
Optimize N+1 query problems in Laravel Eloquent by eager loading only specific columns from related models and handling nested relationships efficiently.
<?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 tags()
{
return $this->belongsToMany(Tag::class);
}
}
class Tag extends Model
{
public function posts()
{
return $this->belongsToMany(Post::class);
}
}
// Fetch users and their posts, but only the 'id' and 'title' from posts
$usersWithPosts = User::with(['posts:id,user_id,title'])->get();
// Fetch posts, their associated user (id, name), and tags (id, name)
$postsWithUserAndTags = Post::with(['user:id,name', 'tags:id,name'])->get();
// Nested eager loading with specific columns:
// Fetch users, their posts (id, title, user_id), and for each post, its tags (id, name)
$usersWithNestedPostsAndTags = User::with([
'posts' => function ($query) {
$query->select('id', 'user_id', 'title')->with([
'tags' => function ($query) {
$query->select('id', 'name');
}
]);
}
])->get();
// Using dot notation for deeply nested relationships
// This implicitly selects all columns for intermediate relationships (Post in this case)
$usersWithPostsAndTagsImplicit = User::with('posts.tags:id,name')->get();
How it works: Eager loading prevents the N+1 query problem by loading related models in fewer queries. This snippet demonstrates two advanced techniques: loading only specific columns from related models (e.g., 'posts:id,user_id,title') to reduce memory and query overhead, and efficiently handling nested relationships. The examples show how to load direct relationships with specific columns, and how to define nested eager loading using closures for more control or using dot notation for simpler cases.