Search code examples
phplaraveleloquentlaravel-7

Laravel Eloquent cursor() out of memory


I have a problem with Laravel's ORM Eloquent cursor() method. Im trying to create some analytics functions for my ecom to get the amount of orders/income and stuff like that, you can check below my code:

$fromDate = Carbon::now()->startOfYear()->toDateString();
$tillDate = Carbon::now()->endOfYear()->toDateString();

$orders = Order::cursor()->whereBetween('created_at', [$fromDate, $tillDate])->whereIn('status', array(1, 2, 3))->filter(function ($order) { 
  return $order; 
});
$countO = $orders->count();
$sumO = $orders->sum('total');

$orders = VoucherOrder::cursor()->whereBetween('created_at', [$fromDate, $tillDate])->where('status', 1)->filter(function ($order) {
  return $order;
});
$countV = $orders->count();
$sumV = $orders->sum('total');

$orders = $countO + $countV;
$income = $sumO + $sumV;

if($orders != 0) {
  $avgOrder = $income / $orders;
}
else {
  $avgOrder = 0;
}

return view('admin.income', compact('orders', 'income', 'avgOrder'));

I used cursor() in order to reduce the memory usage since i'm processing large amounts of data but i still get this error:

Allowed memory size of 536870912 bytes exhausted (tried to allocate 2338688 bytes)

what am i doing wrong? how can i solve?


Solution

  • If you want to reduce memory usage without editing php.ini file, I suggest using chunk than cursor().

    Model::chunk(250, function ($data) {
        foreach ($d as $data) {
            // your code
        }
    });
    

    This will take less memory but do keep in mind this may consume few seconds more for execution in contrast to cursor().