Help please…
These are my migrations
// Test 1 table
public function up(): void
{
Schema::create('test1s', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('desc')->nullable();
$table->timestamps();
});
}
next...
// Test 2 table
public function up(): void
{
Schema::create('test2s', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('desc')->nullable();
$table->foreignId('test2_id')->references('id')->on('test1s')->onDelete('cascade');
$table->timestamps();
});
}
next...
// Test 3 table
public function up(): void
{
Schema::create('test3s', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('desc')->nullable();
$table->foreignId('test3_id')->references('id')->on('test2s')->onDelete('cascade');
$table->timestamps();
});
}
Here are my models and methods in them
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Test1 extends Model
{
use HasFactory;
public function method1(){
return $this->hasMany(Test2::class, 'test2_id', 'id')->with('method2');
}
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class Test2 extends Model
{
use HasFactory;
public function method2(){
return $this->hasMany(Test3::class, 'test3_id', 'id');
}
}
Here’s controller
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppModelsTest1;
class HomeController extends Controller
{
public function index()
{
$res= Test1::with('method1')->get();
return view('home' , compact(['res']));
}
}
The tables are filled with test data, no more than 10 records… At the same time, through the debugger it shows 5 queries and 20 models… If you add records, the number of queries remains 5, and the number of models increases… Moreover, if there are about 1000 records, then There will be more than 10,000 models… Is it possible to optimize this somehow? How?
Upd
Here’s my blade
@foreach ($res as $result)
<h2>{{ $result->name }}</h2>
<ul>
@foreach ($result->method1 as $res2)
<li>
<p>{{ $res2->name }}</p>
<ul>
@foreach ($res2->method2 as $res3)
<li>
<p>{{ $res3->name }}</p>
</li>
@endforeach
</ul>
</li>
@endforeach
</ul>
@endforeach
Here is a screenshot of the debugger
2
Answers
Let’s assume this users-posts-comments situation:
To optimize the Laravel Eloquent query and avoid many model instances in the view, you can eager load the comments along with the posts and users. This will reduce the number of queries executed and improve the performance of your application.
Here’s how you can modify your query and view:
Query Optimization
Load the comments along with the posts and users using eager loading:
View Optimization
You can directly access the comments through the posts that are already eager-loaded, avoiding the need for additional queries:
This approach ensures that all the necessary data is fetched in a single query, reducing the load on your database and improving the performance of your application.
The issue might be related to how you defined your relationships, I had a similar issue when I started programming because I just fetched all and Eloquent, for some reason, went into some circular motion and fetched some tables repeatedly because it had relationships with it..
For this to work, update these migrations:
test3 migration:
then the models
Test1 model:
Test 2 model:
Test 3 model:
Eager load the relationships without nesting so you reduce the number of queries:
and then! blade file update: