首页 > 解决方案 > 在 Laravel 中更新大量条目的最佳方法

问题描述

我有一份来自我的供应商的文件,它可以让我在所有时间都更新库存。我想每小时在我的数据库中进行一次更新,问题是任务太重,页面在将近 10 秒后加载,因为它包含近 10.000 个条目。

这是我的供应商提供的文件:

stock.csv

ref, qty
XXX01, 5
XXX02, 10
XXX03, 3
XXX04, 8
XXX05, 6
...

我得到这个文件并用这个很棒的库将它转换成数组:Laravel Excel 结果:

Array
0 => ['ref' => XXX01, 'qty' => 5]
1 => ['ref' => XXX02, 'qty' => 10]
2 => ['ref' => XXX03, 'qty' => 3]
...


然后我做一个foreach循环来更新我数据库中的每个项目
我的items表是这样的:

id, ref, (...), qty
1, XXX01, 0
2, XXX02, 3
3, XXX03, 1
4, XXX04, 2
5, XXX05, 0

这是我的代码:

// convert .csv into Array
$path = public_path('stock').'/stock.csv';
Excel::setDelimiter(',');
$data = Excel::load($path, function($reader){})->get()->toArray();
// make it in Laravel Collection
$stocks = new Collection($data);

// The treatment
foreach ($stocks as $stock){
    $item = Item::where('ref', $stock['ref'])->first();
    $item->qty = $stock['qty];
    $item->save();
}

// Too long...

Laravel 中是否有其他选项可以使其更快?

标签: phplaravelperformance

解决方案


在不检索记录的情况下更新行肯定会节省很多查询:

foreach ($stocks as $stock){
    Item::where('ref', $stock['ref'])->update(['qty' => $stock['qty']]);
}

如果您经常有很多相同的数量,那么将它们分组可能会更快:

foreach($stocks->groupBy('qty') as $qty => $stocks) {
    Item::whereIn('ref', $stocks->pluck('ref'))->update(['qty' => $qty]);
}

推荐阅读