如何用Prisma高效批量更新含不同数据的多条记录?
批量更新/插入多条记录的最优方案
你当前的实现慢的核心原因是:循环里每次单独await一个upsert操作,等于发起了N次独立的数据库请求,网络往返和数据库连接的开销被不断累加,数据量越大耗时越久。下面给你两种优化方案,都能大幅提升效率:
方案一:Prisma事务 + Promise.all 并行执行
把所有upsert操作打包成Promise数组,用Prisma事务包裹后并行执行。这样所有操作要么全部成功要么全部回滚,同时减少了多次请求的往返开销。
const updateBody = JSON.parse(req.body); try { // 生成所有upsert操作的Promise数组(不要在这里加await) const upsertTasks = updateBody.map(item => prisma.comissions.upsert({ where: { producer: item.producer }, update: { rate: item.rate }, create: item }) ); // 用事务批量执行所有任务 await prisma.$transaction(upsertTasks); } catch (err) { console.error('批量操作失败:', err); }
这个方案的优势是代码和你原来的逻辑几乎一致,不需要改太多,同时保证了数据一致性,适合数据量中等的场景(比如几百条以内)。
方案二:原生SQL批量写入(性能最优)
如果你的数据库支持INSERT ... ON CONFLICT DO UPDATE(比如PostgreSQL、MySQL 8.0+),直接用原生SQL做批量写入是性能最高的方式——只需要一次数据库请求就能处理所有数据。
安全的参数化版本(避免SQL注入)
const updateBody = JSON.parse(req.body); try { // 构造参数占位符和参数列表 const placeholders = updateBody.map((_, idx) => `($${idx * 2 + 1}, $${idx * 2 + 2})` ).join(','); const params = updateBody.flatMap(item => [item.producer, item.rate]); // 执行批量插入/更新的SQL await prisma.$executeRaw(` INSERT INTO comissions (producer, rate) VALUES ${placeholders} ON CONFLICT (producer) DO UPDATE SET rate = EXCLUDED.rate; `, ...params); } catch (err) { console.error('批量操作失败:', err); }
这个方案适合数据量较大的场景(比如上千条),但需要注意数据库的语法差异(比如MySQL用ON DUPLICATE KEY UPDATE),同时必须用参数化查询避免SQL注入风险。
内容的提问来源于stack exchange,提问作者José Carlos
相关产品推荐
相关产品推荐

