Eloquent::steps()

steps() является альтернативой chunk(), но в отличии от последнего, который реализует пагинацию через LIMIT x OFFSET y использует конструкцию WHERE id > x LIMIT y

На реальной БД (pgsql 9.5, over строк таблица) прирост скорости перебора составил более чем в 2 раза и при этом потребовал минимальных изменений кода.

Использование

<?php

use Illuminate\Database\Eloquent\Collection;

Items::steps(1000, function(Collection $items) {
    foreach ($items as $item) {
        /* do stuf */
        $item->touch();
    }
    
    return $item->id ?? false;
});

Единственное отличие: необходимо вернуть значение последнего id для продолжения или false для завершения цикла.

Сравнение скорости

  • chunk() elapsed: 68.626878023148 avr: 0.068402220249176 iteration: 1000 ids: 1000000
  • steps() elapsed: 29.601042985916 avr: 0.029474520921707 iteration: 1000 ids: 1000000

см. /for-test

тем кто дочитал

Да, я знаю, что надо добавить тестов, перевести на английский и вообще оформить pull request. Но я ленивая жопа. Возможно настолько, что не дочитал документацию и в laravel уже давно такое сделано.