Laravel 批次更新資料

在 Laravel 中,如果需要將符合條件的多筆資料進行更新,建議避免使用 foreach + update() 來一筆一筆地操作資料庫,因為這會造成 N+1 次查詢,效能不佳。

從 Laravel 8.42 起,可使用 toQuery() 搭配 update(),直接在資料庫層級執行批次更新,效能更佳且語法簡潔。

使用方式比較

❌ 傳統寫法:每筆更新一次

use App\Models\User;

$users = User::where('status', 'VIP')->get();

foreach ($users as $user) {
    $user->update(['status' => 'Administrator']);
}

此寫法會:

  • 查詢出所有符合條件的使用者
  • 每一筆都執行一次 UPDATE 查詢(N 次)

✅ 建議寫法:使用 toQuery() 直接批次更新

use App\Models\User;

$users = User::where('status', 'VIP')->get();

$users->toQuery()->update([
    'status' => 'Administrator',
]);

此寫法會:

  • 只執行一次 UPDATE 查詢
  • 效能更佳
  • 不會觸發 updatingupdated Eloquent 事件(因為未個別呼叫 ->update()

注意事項

  • toQuery() 會從 Collection 轉回原本的查詢建構器(Query Builder)
  • 適合用在只需更新資料庫欄位、不需要觸發 Eloquent 事件 的情境
  • 若需要觸發模型事件(如記錄異動),仍需使用迴圈逐一更新

官方文件參考