Laravel 8 Upsert批量数据时遇SQLSTATE[HY000]:1390占位符过多错误
解决Laravel 8中Upsert大量数据时占位符过多的错误
错误原因
这个报错是MySQL的限制导致的:MySQL对预处理语句中的占位符数量有上限,当一次性upsert的数据量过大时,生成的SQL语句会包含超过上限的占位符,触发1390 Prepared statement contains too many placeholders错误。
你之前的Chunk用法错误
你使用ReportItem::chunk()的方式不对,这个方法是用来分批查询数据库中的现有数据的,不是用来分块处理要插入/更新的数据集,所以这么写无法解决问题。
正确的解决方法
需要对要处理的$data数据集进行分块,然后在每个数据块中执行upsert:
情况1:$data是Collection实例
// 分块大小可根据每条数据的字段数调整,比如500条(保守值,避免占位符超限) $data->chunk(500)->each(function ($chunk) { ReportItem::upsert($chunk->toArray(), ['someId', 'otherId']); });
情况2:$data是普通数组
先转成Collection再分块:
collect($data)->chunk(500)->each(function ($chunk) { ReportItem::upsert($chunk->toArray(), ['someId', 'otherId']); });
注意事项
- 分块的大小(比如500)可以根据你的数据结构调整:假设每条数据有10个字段,500条就会生成5000个占位符,只要不超过MySQL的
max_prepared_stmt_count默认上限(通常是65535)即可,保守起见用较小的数值更稳妥。 - 如果数据量极大,还可以配合队列异步处理每个分块,避免同步执行时超时。
内容的提问来源于stack exchange,提问作者user3613026
相关产品推荐
相关产品推荐

