Gra*_*avy 3 php mysql laravel eloquent
我有大约80k记录,我每天需要运行几次插入/更新脚本。
INSERT INTO `my_rankings` (`id`, `rank`) VALUES (1,100),(2,99)(3,102)...(80000,3)
ON DUPLICATE KEY UPDATE `rank` = values(`rank`);
Run Code Online (Sandbox Code Playgroud)
这些记录当前为数组格式:
$rankings = [
['id' => 1, 'rank' => 100],
['id' => 2, 'rank' => 99],
['id' => 3, 'rank' => 102],
...
['id' => 80000, 'rank' => 3],
]
Run Code Online (Sandbox Code Playgroud)
有没有一种好的/高性能的方式可以运行上述更新查询?
我看过Eloquent的Model::updateOrCreate(...)。但是我认为我不能将其用于批量插入/更新。
我想避免foreach在$rankings数组上使用和插入/更新单个记录,因为脚本将花费很长时间。
我在/sf/answers/2437100781/下有一个针对此问题的答案,但这远非优雅。
我有一个解决方案-它不优雅,但速度很快。8万条记录为1.6秒。任何更好的解决方案将不胜感激。
$allResults = [
['id' => 1, 'rank' => 100],
['id' => 2, 'rank' => 99],
['id' => 3, 'rank' => 102],
...
['id' => 80000, 'rank' => 3],
];
$rankings = [];
foreach ($allResults as $result) {
$rankings[] = implode(', ', ['"' . $result['id'] . '"', $result['rank']]);
}
$rankings = Collection::make($rankings);
$rankings->chunk(500)->each(function($ch) {
$rankingString = '';
foreach ($ch as $ranking) {
$rankingString .= '(' . $ranking . '), ';
}
$rankingString = rtrim($rankingString, ", ");
try {
\DB::insert("INSERT INTO my_rankings (`id`, `rank`) VALUES $rankingString ON DUPLICATE KEY UPDATE `rank`=VALUES(`rank`)");
} catch (\Exception $e) {
print_r([$e->getMessage()]);
}
});
Run Code Online (Sandbox Code Playgroud)