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++
	}
相关推荐
飞鼠_几秒前
详解c++中的sturct
开发语言·c++
小白学大数据5 分钟前
分布式爬虫核心技术详解与工程实践
开发语言·分布式·爬虫·python
CoderCodingNo9 分钟前
【GESP】C++一级真题 luogu-B4495, [GESP202603 一级] 交朋友
开发语言·c++
The_Second_Coming13 分钟前
MySQL 5.7 学习笔记
笔记·学习·mysql
海寻山19 分钟前
Java内部类:4种类型+实战场景+面试避坑
java·开发语言·面试
梦游钓鱼25 分钟前
stl常用容器说明
开发语言·c++
踏着七彩祥云的小丑34 分钟前
Python——字符串常用操作
开发语言·python
成都易yisdong39 分钟前
基于C#和WMM2025模型的地磁参数计算器实现
开发语言·c#