如何在给定一组键和值的情况下有效地在 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 行的循环仍然需要很长时间。
我有一个非常大(数百万行)的数据库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 行的循环仍然需要很长时间。