I’m working on a function that exports an array of customers to an excel file. It’s about 8 000 customers and I’m running the function as a Job.
However, I keep getting either Maximum execution time exceeded or Allowed memory size of bytes exhausted errors.
I’ve tinkered around quite a lot with lazy collections and/or $collection->chunk() without any improvements. I think I know where the bottlenecks are, but it’s still data that I need in the report.
The thing is, it’s not just a plain list of customers. They all have a few relationships and some of them is nested. For example:
$customer->services
$customer->advisors->roles
$customer->contacts // Phone, email [...]
So when I'm looping over the customers, I need to process the data. Create a list of the services names, filter the advisors depending on their roles, find and place the email addresses and phone numbers in the correct "column" and things like that.
// Simplified example:
$customers = Customer::with(['services', 'advisors.roles', 'contacts'])->get();
$customerReport = collect([]);
foreach($customers->chunk(30) as $chunk) {
foreach($chunk as $customer) {
$customerReport->push([
$customer->name,
$customer->address,
$customer->services->pluck('name')->implode(', '),
]);
}
}
// I'm out of memory or the execution time has been exceeded before this:
createExcelFile($customerReport);
How would you do this in a more efficient way? I guess that the $customerReport array grows too big? I'm thinking about creating a temporary database table and insert data into that instead of creating a large array in memory?
Any help would be much appreciated :)