當使用 Laravel Query Builder 的 cursor 時會造成記憶體不足的問題,網路上雖然查到說可以停掉 MySQL 的 Buffered Query,但實際上設定了之後還是會有記憶體不足的狀況發生。
參考 1:Using Cursor on large number of results causing memory issues
參考 2:Boost Your App’s Performance: Processing Large MySQL Tables with Eloquent ORM
也有人推薦使用 chunk 的方式,但實測過後也是一樣,因為無論如何 MySQL 就是要載入這麼多資料列,因此解題的方向我們朝向減少每一次取得的資料列數量。
這個範例概念是取得最新的 id,並且每次取得一千筆資料做處理,如此一來便能解決載入一次載入大量資料的問題。
$latest_id = DB::table('records')->latests()->first()->id;
$parts = ceil($latest_id / 1000);
for ($i = 0; $i <= $parts; $i++) {
$records = DB::table('records')->whereIn('id', [$i, $i + 1000])->get();
// 處理 records
}