Очень медленно производится цикл по большим массивам данных. Как ускорить?

Формирую отчет из БД. Данные получаю +- за 1 сек. Строк 300 000+. Необходимо производить некоторые манипуляции в каждой итерации. Одна итерация выполняется в среднем 0.003 сек. Итог - больше 15 минут производится цикл. В результате формируется ассоциативный массив с суммарной информацией (50 строк примерно). Но это очень долго.

Вопрос: Есть предположения как ускорить или кто какие использует фишки для ускорения работы с большим объёмом данных?

update:

Производимые манипуляции:

      if (!isset($consumption[$material_name]['category_name'])) {
        $consumption[$material_name]['category_name'] = $category_name;
      }

      if (!isset($consumption[$material_name]['material_name'])) {
        $consumption[$material_name]['material_name'] = $material_name;
      }

      if (isset($consumption[$material_name][$date])) {
        $consumption[$material_name][$date] += $consumption_value;
      } else {
        $consumption[$material_name][$date] = $consumption_value;
      }

      if (isset($consumption_by_invoices["{$material_name}_$date"][$invoice_id])) {
        $consumption_by_invoices["{$material_name}_$date"][$invoice_id] += $consumption_value;
      } else {
        $consumption_by_invoices["{$material_name}_$date"][$invoice_id] = $consumption_value;
      }

Ответы (1 шт):

Автор решения: Егор Банин

Самый очевидный способ ускорить выполнение операций в больших циклах -- разделить цикл на циклы поменьше и запустить их параллельно.

Было:

<?php // test.php

$start = time();
$result = 0;
for ($i = 0; $i < 100000; ++$i) {
    ++$result;
    usleep(100);
}

printf("%d\nза %d сек\n", $result, time() - $start);

Стало:

<?php // test.php

if (count($argv) > 1) {
    [, $limit] = $argv;
    $result = 0;
    for ($i = 0; $i < $limit; ++$i) {
        ++$result;
        usleep(100);
    }
    echo "$result\n";
    exit(0);
} else {
    $start = time();
    exec('echo 25000 25000 25000 25000 | xargs -P 4 -n 1 php test.php', $results);
    $sum = 0;
    foreach ($results as $result) {
        $sum += (int) $result;
    }

    printf("%d\nза %d сек\n", $sum, time() - $start);
}
→ Ссылка