Может быть, преобразовав loadSourceSystemData в генератор и затем обработав данные в чанках, таким образом, вы будете загружать не более 10000 строк одновременно, поскольку они не собираются в одну большую коллекцию, их можно автоматически освобождать.
<?php
function loadSourceSystemData(): iterable
{
$connection = $this->getOracleConnection();
DB::disableQueryLog();
$connection->disableQueryLog();
$package_size = 10000;
$offset = 0;
do {
$records = $connection->query()->from('ZVPCP003')
->take($package_size)
->offset($offset)
->get();
$offset += $package_size;
yield collect($records);
} while(!empty($records));
}
foreach($this->loadSourceSystemData() as $collection) {
foreach($collection as $row) {
// Process row here
}
}
Обновление
Я пытался загрузить данные из CSV-файла, чтобы проверить накладные расходы, и при использовании массивов занимает примерно на 70% больше памяти, чем при использовании объектов.
Для 500000 строк, таких как «P80, массив A142900,2012,6,35» занял около 213 МБ, а массив объектов - 136 МБ.
class Item {
public $a;
public $b;
public $c;
public $d;
public $e;
}
if (($handle = fopen("data.csv", "r")) !== FALSE) {
$row = 0;
$list = [];
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$item = new Item();
$item->a = $data[0];
$item->b = $data[1];
$item->c = $data[2];
$item->d = $data[3];
$item->e = $data[4];
$list[] = $item;
//$list[] = $data;
}
fclose($handle);
$m = memory_get_usage(true) / 1000 / 1000;
echo "Rows ", count($list), " Memory ", $m, "MB \n";
}
Обновление 2
Подробнеепамять может быть сохранена, если данные преобразуются в конкретные типы, например. int, и если некоторые столбцы имеют много повторяющихся значений, то можно использовать кэширование.
class Name {
public $name;
public function __construct($name)
{
$this->name = $name;
}
}
class NameCache {
private $cache = [];
public function getName(string $name) {
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
$item = new Name($name);
$this->cache[$name] = $item;
return $item;
}
}
$nameCache = new NameCache();
$item = new Item();
$item->a = $nameCache->getName($data[0]);
$item->b = $nameCache->getName($data[1]);
$item->c = (int)$data[2];
$item->d = (int)$data[3];
$item->e = (int)$data[4];
При этом объем памяти был уменьшен с 136 МБ до 75 МБ.