You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:15:29