Be careful with Iterator
!
According to my benchmarks it seems Iterator loads all data at same time! It loads in a flat array, not objects - so it takes less memory.
I prefer old-fashion way to loop the collection - page by page:
$collection->setPageSize(50);
$pages = $collection->getLastPageNumber();
for ($pageNum = 1; $pageNum<=$pages; $pageNum++) {
$collection->setCurPage($pageNum);
foreach ($collection as $item) {
//Do something.
}
$collection->clear();
}
Full example is here:
https://magento.stackexchange.com/a/273437/48222
Iterator.Benchmark:
Code
print_mem();
$iterator = $this->iteratorFactory->create();
$iterator->walk($collection->getSelect(), [
function ($batch) {
print_mem();
$this->batchProcessor->executeRow($batch);
}
]);
Output
//Before `Iterator::walk`
^ "The script is now using: 87 403 KB of memory."
^ "Peak usage: 87 943KB of memory."
//Inside `Iterator::walk`
^ "The script is now using: 1 315 666 KB of memory."
^ "Peak usage: 1 315 666 KB of memory."
Collection page-by-page.Benchmark:
Code
print_mem();
$collection->setPageSize(10);
$pages = $collection->getLastPageNumber();
for ($pageNum = 1; $pageNum<=$pages; $pageNum++) {
$collection->setCurPage($pageNum);
foreach ($collection as $batch) {
print_mem();
$this->batchProcessor->execute($batch);
}
$collection->clear();
}
Output
//Before
^ "The script is now using: 87 403 KB of memory."
^ "Peak usage: 87 943 KB of memory."
//Inside `foreach(collection)`
^ "The script is now using: 97 013 KB of memory."
^ "Peak usage: 106 350 KB of memory." //an order of magnitude less