以前、Laravelで大量データをgetする場合はchunkを、と投稿しました。
ですが、注意点があります。
例えば結果が100件のBuilderに対して10件ずつのchunkを発行した場合、
最初の1-10件についてクロージャが実行された後、
次は10件をスキップして10件を取得(つまり11-20)、
その次は20件をスキップして10件を取得(つまり21-30)...
以上を逐次で取得した結果が0になるまで繰り返すというものです。
ですので、例えばクロージャ内で対象モデルのデータに更新を行い、
当初の条件と総数が異なるケースでは、
想定した動作とは異なる可能性が出てきます。
例えば、
//現在日時は2015/11/11 00:00:00
Person::where('updated_at', '<', '2015/11/10')
->chunk(10, function ($persons) {
$persons->each(
function ($person) {
$person->touch();
}
);
});
上記だと、どんどん対象データが減っていくので、
結果として更新されないデータが出てきます。
ですのでこのような場合は、一旦primary idのみgetで一括取得して変数に保持しておき、
その後1件ずつ処理するようなパターンが考えられるでしょうか。
それから、上記chunkの例にはまだ問題があります。
それは、確実なソート順を設定しておかないと、
取得するタイミングによっては結果セットの並び順が変わってしまう可能性がある為です。
従いまして、chunkを利用する際にはorderBy(id
)のように
プライマリーキーを指定するということが必要になるでしょう。
※プライマリーキーがUUIDなどの場合、別途ソート順を考える必要もあるでしょうが。