はじめに
最近、大量のデータを扱う対応をいたしました
もちろんそのまま取得すると動作が重くなったりサーバーへの負荷が重すぎてしまいます
そのため、取得数の制限をしたかったのですが、すべてのデータを使用する必要があったのでせめて分割で取得できればなと思いました
そんな中で見つけたchunk
が今回のような状況にピッタリだったので調べた内容を記事にします
chunk
メソッドとは
-
chunk
メソッドは、指定したサイズごとにクエリ結果を分割して取得して、第2引数のクロージャ関数で処理を実行します- 分割したレコードをそのまま参照できるのではなく、分割したうえで何かしらの処理を実行させなければならなりません
$users = User::chunk(100, function($users){});
echo $users;
// 1
chunk
の返り値はbool
ですので代入しても取得したデータは使えないのです
- 第1引数に分割する件数を設定します
- 例:100を設定すると、100件取得して処理したら次の100件を取得する
- 第2引数にコールバック関数を設定します
- 呼び出し元で行う処理が入ります
- これがfalseなら処理は終了されます
参考Github
chunk
の使い方
User::chunk(100, function ($users) {
foreach ($users as $user) {
// ユーザーに関する処理
}
});
上記では、ユーザーデータを100件ずつ分割して処理しています
get
メソッドとの比較
-
get
メソッドの問題点- 大量のデータを使用する際に
get
メソッドを使用すると、一度にすべてのデータをメモリにロードするため、大量のデータを処理する際にメモリ不足やパフォーマンスの低下を引き起こす可能性があります
- 大量のデータを使用する際に
get
メソッドを使用した例
$users = User::get(); // 全ユーザーデータを一度に取得
foreach ($users as $user) {
// ユーザーに関する処理
}
上記の例では、すべてのユーザーデータを一度に取得して処理しています
この方法は少量の(数十件くらい)のデータでは問題ありませんが、数百件以上のデータではメモリ不足や処理の遅延が発生してしまいます
chunk
の具体的な使用例
- 大量データのバッチ処理
- バッチ処理を行う際に、
chunk
メソッドを使うことでメモリ使用量を抑えつつ、大量データを効率的に処理できます
- バッチ処理を行う際に、
Order::chunk(1000, function ($orders) {
foreach ($orders as $order) {
// バッチ処理ロジック
// 例えば、注文データを処理してレポートを生成する
}
});
- データエクスポート
- データエクスポートに関しても大量データを効率的に処理できるようになります
Product::chunk(500, function ($products) {
// CSVエクスポートロジック
// 例えば、製品データをCSVファイルに書き出す
});
まとめ
大量データを扱う際は可能であればgetではなくchunk
と使って分割取得し、
サーバー負荷やメモリ不足、パフォーマンスの低下を未然に防ぎましょう!
参考リンク