golang 高性能的 MySQL 数据导出

需求

  • 导出 MySQL 数据

分析:

  • 一次性 select 大量数据带来的问题

性能问题:

数据库负载:大量数据查询会增加数据库的CPU、内存和I/O负担,可能影响其他操作。

网络传输:大数据量传输会占用大量带宽,导致网络延迟或超时。

内存消耗:

服务器内存: 消耗太大,影响其他业务运行

导出方式对比

  • 条件:
  • 200 万数据
  • 查询全表耗时 3s
方案1:快照导出(耗时:1.5s)
go 复制代码
data, err := db.Query("select * from user2")
	if err != nil {
		log.Fatal("err1:", err)
	}
	defer data.Close()

	columns, err := data.Columns()
	if err != nil {
		log.Printf("[error] %v \n", err)
	}

	l := len(columns)

	val := &User{}
	valPointer := make([]interface{}, l)
	valPointer[0] = &val.Id
	valPointer[1] = &val.Name
	valPointer[2] = &val.Tag
	valPointer[3] = &val.Phone
	valPointer[4] = &val.Create_time

	//计数
	num := 0

	for data.Next() {
		err := data.Scan(valPointer...)
		if err != nil {
			log.Fatal("err5:", err)
		}
	}
方案2: 偏移分页(耗时:4s)
go 复制代码
	// 定义分页参数
	starId := 0
	pageSize := 2000
	// 定义查询条件
	var users []User
	// 执行分页查询
	for {
		result := db.Limit(pageSize).Where("id >= ?", starId).Find(&users)
		if result.Error != nil {
			log.Fatal("err5:", result.Error)
		}

		if len(users) < pageSize {
			break
		}
		starId = users[len(users)-1].Id
	}
方案 3:普通分页(耗时:4min40s)
go 复制代码
// 定义分页参数
	page := 1
	pageSize := 2000

	// 导出数据
	for {
		var users []User
		result := db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&users)
		if result.Error != nil {
			log.Fatal("err5:", result.Error)
		}
		if len(users) < pageSize {
			break
		}
		page++
	}
相关推荐
jokr_6 分钟前
C++ 字符串与内存操作函数深度解析
java·开发语言·c++
Elieal12 分钟前
深入浅出 ArrayList:从基础用法到底层原理的全面解析(上)
开发语言
CodeCraft Studio9 小时前
3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
开发语言·3d·c#·3d渲染·aspose·3d文件格式转换·3d sdk
superlls9 小时前
(Redis)主从哨兵模式与集群模式
java·开发语言·redis
一只叫煤球的猫10 小时前
看到同事设计的表结构我人麻了!聊聊怎么更好去设计数据库表
后端·mysql·面试
chenglin01610 小时前
C#_gRPC
开发语言·c#
骑驴看星星a10 小时前
数学建模--Topsis(Python)
开发语言·python·学习·数学建模
遇见你的雩风11 小时前
【MySQL】CRUD基础详解
数据库·mysql
tju新生代魔迷12 小时前
C语言宏的实现作业
c语言·开发语言
yueyuebaobaoxinx12 小时前
MATLAB 与 Simulink 联合仿真:控制系统建模与动态性能优化
开发语言·matlab·性能优化