事务性能差主因是事务边界、索引设计、批量策略与锁行为不匹配业务;应小粒度事务、批量操作、确保索引有效、避免隐式转换,并按场景调优日志刷盘策略。

事务中插入和更新性能差,往往不是 SQL 写得不够“炫”,而是事务边界、索引设计、批量策略和锁行为没对齐业务场景。核心思路是:减少锁持有时间、降低日志写入压力、避免隐式类型转换和全表扫描。
合理控制事务粒度,避免大事务
一个事务内处理几万行数据,会导致锁升级(如行锁→表锁)、undo 日志暴涨、主从延迟加剧,甚至触发锁等待超时。关键不是“要不要事务”,而是“事务该包多小”。
- 按业务逻辑自然切分:比如导入订单,按“单个订单”或“每 100 个订单”启一个事务,而非整个文件包进一个事务
- 显式提交后立即释放锁:用 COMMIT 主动结束,不要依赖连接关闭自动提交(尤其在应用层长连接中)
- 读操作尽量移出事务:如校验前置状态(库存是否充足)放在事务外查,只把真正要改的数据放进事务内
批量操作代替逐条执行
单条 INSERT / UPDATE 执行 1000 次,远慢于一次批量操作。网络往返、解析开销、日志刷盘次数都成倍增加。
网趣购物系统静态版支持网站一键静态生成,采用动态进度条模式生成静态,生成过程更加清晰明确,商品管理上增加淘宝数据包导入功能,与淘宝数据同步更新!采用领先的AJAX+XML相融技术,速度更快更高效!系统进行了大量的实用性更新,如优化核心算法、增加商品图片批量上传、谷歌地图浏览插入等,静态版独特的生成算法技术使静态生成过程可随意掌控,从而可以大大减轻服务器的负担,结合多种强大的SEO优化方式于一体,使
- INSERT 推荐用 INSERT INTO ... VALUES (...), (...), (...) 多值语法,MySQL 单次最多支持约 1000 行(受 max_allowed_packet 限制)
- UPDATE 若需按条件批量更新,优先用 JOIN + UPDATE 或临时表 + 覆盖更新,避免在应用层循环拼 WHERE id IN (...)(IN 列表过长会失效索引)
- PostgreSQL 可用 INSERT ... ON CONFLICT DO UPDATE 实现 upsert 批量去重更新;MySQL 8.0+ 支持 INSERT ... ON DUPLICATE KEY UPDATE 同理
确保关键字段有高效索引,且无隐式失效
UPDATE 的 WHERE 条件、INSERT 的唯一约束校验、事务中 JOIN 的关联字段,若缺失索引或索引被绕过,就会触发全表扫描或锁全表,性能断崖下跌。
- 检查执行计划:对慢事务中的 UPDATE/INSERT 语句运行 EXPLAIN(MySQL)或 EXPLAIN ANALYZE(PostgreSQL),确认是否走了预期索引
- 警惕隐式转换:如 WHERE status = '1' 对 int 类型字段查询,或 JOIN 时一边是 utf8mb4、一边是 latin1,都会让索引失效
- 复合索引注意最左匹配:UPDATE ... WHERE user_id = ? AND created_at > ?,索引应为 (user_id, created_at),反过来则无法加速
调整事务日志与刷盘策略(DBA 级优化)
频繁小事务的瓶颈常卡在磁盘 I/O——每次 COMMIT 都可能触发 redo log 刷盘。可在可控范围内适度放宽持久性保障,换取吞吐提升。
- MySQL:将 innodb_flush_log_at_trx_commit = 2(日志写 OS 缓存但不强制刷盘),牺牲极小崩溃丢失风险,换取 3–5 倍写入吞吐
- PostgreSQL:调低 synchronous_commit = off(异步提交),配合 wal_writer_delay 控制 WAL 刷盘节奏
- 注意:金融类强一致性场景禁用上述配置;生产调整前务必压测验证恢复能力










