如何在给定一组键和值的情况下有效地在 Eloquent 中进行批量更新

How to mass update in Eloquent given an array of keys and values efficiently

我有一个非常大(数百万行)的数据库table,我需要从第 3 方向每一行添加一些缺失的数据。

数据源有一个 'reference key',这是我映射到 table

中正确项目的唯一方法

每行需要更新 1 个数字

我可以遍历第 3 方数据源并使用唯一标识符对每一行执行 eloquent 更新,但从我的测试来看这非常慢:

Orders
  id,  reference_key,  new_value
  int, string,         double(8,2)

foreach ($xml as $row) {
    Order::where('reference_key', $reference_key)
        ->update('new_value', (float)$row->new_value);
}

有没有更有效的方法可以做到这一点?

我会像这样一次性完成更新语句:

UPDATE OrderTable
INNER JOIN table_to_fill ON OrderTable.refkey = table_to_fill.refkey
SET OrderTable.value = table_to_fill.value

Eloquent 在管理复杂的关系、连接、预加载模型等方面非常强大......但这种抽象有性能成本。每个模型都必须创建、填充和保存,它包含了大量您在这个精确用例中不需要的功能。

在编辑几千条甚至几百万条记录时,使用Eloquent模型是非常低效的。相反,您可以使用 laravel 查询生成器或原始 SQL 语句。

我会推荐这种方法:

$table = Db::table('orders');
foreach ($xml as $row) {
    $table->where('reference_key', $reference_key)
        ->update('new_value', (float)$row->new_value);
}

但你也可以这样做:

foreach ($xml as $row) {
    DB::statement('UPDATE orders SET new_value=? WHERE reference_key=?', 
    [(float)$row->new_value, $reference_key]);
}

它会显着减少您的执行时间,但是数百万 XML 行的循环仍然需要很长时间。