Lex de Willigen
Lex de Willigen

Reputation: 406

Laravel: improve performance when having multiple eager loading queries

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

Answers (1)

Rwd
Rwd

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

Related Questions