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++
	}
相关推荐
linweidong1 小时前
Go开发简历优化指南
分布式·后端·golang·高并发·简历优化·go面试·后端面经
苇柠1 小时前
Java补充(Java8新特性)(和IO都很重要)
java·开发语言·windows
白总Server1 小时前
C++语法架构解说
java·网络·c++·网络协议·架构·golang·scala
156082072192 小时前
在QT中,利用charts库绘制FFT图形
开发语言·qt
有时间要学习2 小时前
MySQL——事务
数据库·mysql
小鹭同学_2 小时前
Java基础 Day27
java·开发语言
EdmundXjs3 小时前
IO Vs NIO
java·开发语言·nio
why1513 小时前
字节golang后端二面
开发语言·后端·golang
RedJACK~3 小时前
【Go语言】Ebiten游戏库开发者文档 (v2.8.8)
开发语言·游戏·golang
lyh13443 小时前
【Go语言生态】
开发语言