Reputation: 406
I'm trying to improve the performance of my laravel application. I was already able to reduce the amount of queries from 68 to 20 by removing lazy loading in my views.
However, using eager loading, still 20 queries remain that do almost the same thing. My code looks like this:
$products = [
'latest' => Product::with('vehicle', 'brand', 'type', 'photos')->withoutGlobalScope(ProductScope::class)->latest()->take(5)->get(),
'most_viewed' => Product::with('vehicle', 'brand', 'type', 'photos')->withoutGlobalScope(ProductScope::class)->mostViewed()->take(5)->get(),
'nearest' => Product::with('vehicle', 'brand', 'type', 'photos')->withoutGlobalScope(ProductScope::class)->nearest($address)->take(5)->get(),
];
This results in 15 queries (5 each) since every time the relations will also be queried again. Can these queries be combined in such a way that it might be reduced to 7 queries instead of 15?
Upvotes: 1
Views: 1071
Reputation: 35190
Since the different collections should be passed by reference you should be able to combine them in to a single Eloquent Collection and then use Lazy Eager Loading:
$products = [
'latest' => Product::withoutGlobalScope(ProductScope::class)->latest()->take(5)->get(),
'most_viewed' => Product::withoutGlobalScope(ProductScope::class)->mostViewed()->take(5)->get(),
'nearest' => Product::withoutGlobalScope(ProductScope::class)->nearest($address)->take(5)->get(),
];
//Merge the different Product collections into one for the lazy eager loading
$collection = new \Illuminate\Database\Eloquent\Collection();
foreach ($products as $items) {
foreach ($items as $model) {
$collection->push($model);
}
}
$collection->load('vehicle', 'brand', 'type', 'photos');
//$products should now contain the different collections but with the additional relationships.
The original collections in the $products
array should now have all the relationships loaded but it should have only performed 4 queries instead of 12 for the relationships.
Upvotes: 1