0

0

如何优化Golang数据库批量写入性能_Golang SQL批量操作优化示例

P粉602998670

P粉602998670

发布时间:2026-01-08 17:28:41

|

985人浏览过

|

来源于php中文网

原创

批量INSERT比单条快5–20倍,因减少网络往返、日志刷盘和索引更新;需控制单批100–500行,避免超max_allowed_packet等限制;推荐用pgx.Batch等安全高效方式实现。

如何优化golang数据库批量写入性能_golang sql批量操作优化示例

为什么 INSERT INTO ... VALUES (...), (...), (...) 比循环单条 INSERT 快得多

单条 INSERT 每次都触发一次网络往返、一次事务日志刷盘、一次索引更新,而批量拼接后一次提交,能显著减少这些开销。PostgreSQL 和 MySQL 都对多值 INSERT 做了深度优化,实测 1000 行数据,批量写入通常比逐条快 5–20 倍。

但要注意:不能无限制拼接。MySQL 默认 max_allowed_packet 通常为 4MB,PostgreSQL 的 statement_timeout 和内存限制也会制约单条语句长度。建议单批控制在 100–500 行之间,具体按字段数和平均行大小反推。

  • 字段越多、文本越长,单批行数应越少
  • 使用 pgx(PostgreSQL)或 mysql 驱动时,避免手动字符串拼接 SQL——用参数化批量插入
  • SQLite 不支持多值 INSERT 的参数化形式(如 VALUES (?, ?), (?, ?)),需改用 INSERT ... SELECT 或启用扩展

pgx.Batch 实现安全高效的 PostgreSQL 批量写入

pgxBatch 机制不是简单拼 SQL,而是复用连接、预编译语句、批量发送参数,规避 SQL 注入且性能接近原生 COPY。它内部按配置的 BatchSize 分片,自动处理失败重试边界(但不自动回滚整批)。

conn, _ := pgx.Connect(ctx, connString)
defer conn.Close(ctx)

b := &pgx.Batch{}
for _, u := range users {
    b.Queue("INSERT INTO users(name, email) VALUES($1, $2)", u.Name, u.Email)
}

br := conn.SendBatch(ctx, b)
defer br.Close()

for i := 0; i < len(users); i++ {
    _, err := br.Exec()
    if err != nil {
        // 注意:此处 err 仅对应第 i 个语句,非整批
        log.Printf("failed on item %d: %v", i, err)
    }
}
  • 不要在循环里调用 br.Exec() 后立刻处理结果——这会退化成类逐条行为;应先全部 Exec() 完再统一检查
  • 若需原子性(整批成功或全失败),必须显式开启事务:tx, _ := conn.Begin(ctx),再用 tx.SendBatch()
  • Batch 不支持返回 sql.Result.LastInsertId(),如需主键,改用 RETURNING id 并解析每条响应

MySQL 场景下慎用 exec.QueryRow 替代 exec.Exec 批量插入

有人误以为 “用 QueryRow 能拿到自增 ID 就更‘完整’”,但在批量场景中,这是严重误区:QueryRow 强制等待单条语句返回,彻底破坏批量并发能力,性能可能比纯 Exec 慢一个数量级。

立即学习go语言免费学习笔记(深入)”;

uBrand
uBrand

一站式AI品牌创建平台,在线品牌设计,AI品牌策划,智能品牌营销;uBrand帮助创业者轻松打造个性品牌!

下载

正确做法是:不需要即时 ID → 用 Exec + 多值 INSERT;需要 ID → 改用 INSERT ... VALUES (...), (...) RETURNING id(MySQL 8.0.19+)或分批后查最大 ID 范围(需唯一有序字段)。

  • MySQL 驱动(如 go-sql-driver/mysql)不支持多值 INSERTRETURNING,得靠业务层补查
  • 如果表有唯一约束且写入可能冲突,优先用 INSERT IGNOREON DUPLICATE KEY UPDATE,避免事务因唯一键错误中断
  • 开启 multiStatements=true 参数虽支持多语句,但有注入风险且多数 ORM 不兼容,不推荐

真正影响吞吐的隐藏瓶颈:事务提交频率与连接池设置

即使用了批量插入,如果每批都开新事务或连接池太小,性能仍上不去。典型表现是 CPU 利用率低、数据库连接数打满、pg_stat_activity 显示大量 idle in transaction

  • 把多批写入包在一个事务里(如 10 批 × 200 行 = 2000 行/事务),可减少 WAL 刷盘次数;但事务太大又增加锁持有时间和 OOM 风险
  • database/sqlSetMaxOpenConns 建议设为数据库允许的最大连接数 × 0.8;SetMaxIdleConns 至少等于并发批量协程数
  • PostgreSQL 中,synchronous_commit = off 可大幅提升写入速度(牺牲极小概率崩溃丢数据),测试环境可开,生产需权衡

批量写入的复杂点从来不在“怎么拼 SQL”,而在于平衡事务粒度、连接复用、错误恢复和数据库侧资源水位——调参前务必用 EXPLAIN ANALYZEpg_stat_statements 看真实执行计划。

相关文章

数码产品性能查询
数码产品性能查询

该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

177

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

226

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

336

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

189

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

Golang 分布式缓存与高可用架构
Golang 分布式缓存与高可用架构

本专题系统讲解 Golang 在分布式缓存与高可用系统中的应用,涵盖缓存设计原理、Redis/Etcd集成、数据一致性与过期策略、分布式锁、缓存穿透/雪崩/击穿解决方案,以及高可用架构设计。通过实战案例,帮助开发者掌握 如何使用 Go 构建稳定、高性能的分布式缓存系统,提升大型系统的响应速度与可靠性。

58

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.7万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 785人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号