How can I improve the performance of a query with the following characteristics (this is a simulation to exemplify):
public function getData()
{
$itens = Item::orderBy('id_item', 'DESC')->get();
foreach($itens as $item){
$item->games = $item->games()->get();
foreach( $item->games as $player){
$item->players = $player->players()->get();
}
}
return response()->json(['success'=>true, 'itens'=>$itens]);
}
In my real case, the foreach returns a lot of data with performance problems;
The Waiting (TTFB), that is, the time the browser is waiting for the first byte of a response, takes almost 27s
CodePudding user response:
class Item extends Model{
// ...
public function games(){
return this->hasMany(Game::class);
}
public function players(){
return this->hasManyThrough(Player::class ,Game::class);
}
}
public function getData()
{
$itens = Item::orderBy('id_item', 'DESC')->with('games','players')->get();
return response()->json(['success'=>true, 'itens'=>$itens]);
}
That will result in 3 queries and the output will be like:
[
// item 0 ...
[
// item data
[
// games
],
[
// players
]
],
// other items
]
CodePudding user response:
Here you go
public function getData()
{
$items = Item::with('games.players')->orderBy('id_item', 'DESC')->get();
return response()->json(['success'=>true, 'items'=>$items]);
}
CodePudding user response:
Code based solutions:
- Looping on array is around 2 times cheaper than looping on List.
- A 'for' loop is much faster than 'foreach'
a other solutio is:
- Filtering unnecessary parts for running the loop