前言

golang可以轻易制造高并发,在某些场景很合适,比如爬虫的时候可以爬的更加高效。但是对应某些场景,如文件读写,数据库访问等IO为瓶颈的场合,就没有什么优势了。

前提基础

1、golang数据库访问 
在golang中数据库访问使用”database/sql”包提供的接口,不同的数据库,比如pg、mysql只需要提供对应的驱动就可以了。注意”database/sql”包提供的接口只针对关系型数据库,nosql如redis和mongodb都是直接使用对应的客户端包,不实现”database/sql”包提供的接口。关于”database/sql”包,这里不做讲述,后续在基础回顾上巩固下。总体上就是提供了连接、事务处理、还有就是打开的时候注意打开的时候并没有连接,而是产生一个池,每次有交互的时候才产生一个连接(事务交互除外)。

2、数据库插入优化基础 
1)插入无索引表会比插入有索引的表快,毕竟建立索引总是要增加一些额外操作 
2)插入小表比插入大表快,业务一般插入速度是以条数计算,大表一条记录比较大,需要IO的时间比较长。 
3)多个连接一起插入会比单连接快,因为mysql不是单线程。 
4)日志缓存增大可以加快插入速度,因为减少了IO访问次数。 
5)一次插入多条数据可以加快插入速度。

实践经验

ps:以小表做实验,都用一个环境,比较差异。 
表结构:

create table lamp(
id bigint not null primary key,
state char(1),
collecttime timestamp);

1、无任何优化,一条条插入,且使用同一个链接 
代码片段:

fmt.Println(time.Now().Unix())
_, err = db.Prepare("INSERT INTO lamp (id, state, collecttime)VALUES(?,'0', '20180103002930')")
if err != nil {
fmt.Println(err)
return
}
for i := 0; i < 100000; i++ {
_, err := db.Exec(execstring + data)
if err != nil {
fmt.Println(err)
return
}
}
fmt.Println(time.Now().Unix())

结果:

1514911765

1514912248

使用了483s 平均100000/500 大概是200次每秒。

2、单连接,使用事务。

fmt.Println(time.Now().Unix())
insert, err = db.Prepare("INSERT INTO lamp (id, state, collecttime)VALUES(?,'0', '20180103002930')")
if err != nil {
fmt.Println(err)
return
}
begin, err := db.Begin()
if err != nil {
fmt.Println(err)
return
}
for i := 0; i < 100000; i++ {
_, err := begin.Stmt(insert).Exec(i)
if err != nil {
fmt.Println(err)
return
}
}
err = begin.Commit()
if err != nil {
fmt.Println(err)
return
}
fmt.Println(time.Now().Unix())

运行结果

1514910923

1514911049

使用了129s 平均100000/125, 约为800次每秒

3、批量插入,每1W条执行一次插入操作。,注意max_allowed_packet要设置的足够大

fmt.Println(time.Now().Unix())
for i := 0; i < 1000; i++ {
for j := i * 10000; j < i*10000+10000; j++ {
if j < i*10000+9999 {
id := strconv.Itoa(j)
onedata := "(" + id + ", '0', '20180103002930'), "
data = data + onedata
} else {
id := strconv.Itoa(j)
onedata := "(" + id + ",'0', '20180103002930')"
data = data + onedata
}
}
_, err := db.Exec(execstring + data)
if err != nil {
fmt.Println(err)
return
}
}
fmt.Println(time.Now().Unix())

结果:

1514969811

1514970318

使用了507s 平均10000000/500, 约为2W次每秒

4、并发插入,使用100个协程插入

fmt.Println(time.Now().Unix())
intertnumber := 0
for i := 0; i < 10; i++ {
value := i
go func() {
execstring := "INSERT INTO lamp (id, state, collecttime)VALUES"
for k := value; k < 1000; k = k + 10 {
data := " "
for j := k * 10000; j < k*10000+10000; j++ {
if j < k*10000+9999 {
id := strconv.Itoa(j)
onedata := "(" + id + ", '0', '20180103002930'), "
data = data + onedata
} else {
id := strconv.Itoa(j)
onedata := "(" + id + ",'0', '20180103002930')"
data = data + onedata
} }
//fmt.Println(execstring + data)
_, err := db.Exec(execstring + data)
if err != nil {
fmt.Println(err)
return
}
intertnumber = intertnumber + 10000
}
}()
}
for intertnumber < 9999999 {
time.Sleep(1 * time.Second)
}
fmt.Println(time.Now().Unix())

运行结果:

1514974432

1514974796

使用了363s 平均10000000/500, 约为2.7W次每秒

4、1千W条数据,开1000个协程做插入操作,每次插入1W条数据。mysql最大连接数设置为2048 
运行结果:

mysql宕机,CPU,MEM使用过高,IO使用并不高。

总结:

从程序层面上看: 
1、使用事务会比较快一些。 
2、多连接插入会快很多,当读写成为瓶颈的时候,效果就不太明显。 
3、一次插入多条数据也会快很多。 
4、高并发大量插入请求,mysql服务的应对措施是宕机,而不是拒绝请求。(这个跟笔者代码也有一定关系,因为100个协程前面都是再抢CPU构造插入请求,几乎都是同时向mysql请求),mysql在高并发场景,如果承受不住会宕机,这点在设计上需要注意。

原文:http://blog.csdn.net/m0_38132420/article/details/78964433

使用golang插入mysql性能提升经验的更多相关文章

  1. Mysql学习总结(38)——21条MySql性能优化经验

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情. 当我们去设计数据库表结构,对操作数 ...

  2. MySQL性能优化经验

    核心 不做运算 md5() Order By Rand() 控制单表数据量 保持表字段苗条 平衡范式与冗余 拒绝3B Big SQL Big Transaction Big Batch 字段 用好数值 ...

  3. 10个提升MySQL性能的小技巧

    从工作量分析到索引的三条规则,这些专家见解肯定会让您的MySQL服务器尖叫. 在所有的关系数据库中,MySQL已经被证明了完全是一头野兽,只要通知停止运行就绝对不会让你多等一秒钟,使你的应用置于困境之 ...

  4. paip.提升性能---mysql 性能 测试以及 参数调整.txt

    paip.提升性能---mysql 性能 测试以及 参数调整.txt 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://b ...

  5. MySQL 8.0 —— CATS事务调度算法的性能提升

    原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...

  6. MYSQL性能优化的最佳20+条经验

    MYSQL性能优化的最佳20+条经验 2009年11月27日 陈皓 评论 148 条评论  131,702 人阅读 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数 ...

  7. 【转】MySQL批量SQL插入各种性能优化

    原文:http://mp.weixin.qq.com/s?__biz=MzA5MzY4NTQwMA==&mid=403182899&idx=1&sn=74edf28b0bd29 ...

  8. 二十种实战调优MySQL性能优化的经验

    二十种实战调优MySQL性能优化的经验 发布时间:2012 年 2 月 15 日 发布者: OurMySQL 来源:web大本营   才被阅读:3,354 次    消灭0评论     本文将为大家介 ...

  9. 使用ThinkPHP开发中MySQL性能优化的最佳21条经验

    使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更 ...

随机推荐

  1. IDEA 中用好 Lombok,撸码效率至少提升5倍!

    来 源:http://t.cn/EXhxRzV 以前的Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString:异常处理:I/O流的关闭操作等等,这些样板代码既没 ...

  2. 【Offer】[13] 【机器人的运动范围】

    题目描述 思路分析 Java代码 代码链接 题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和 ...

  3. ssh的秘钥认证

    ssh秘钥认证简述 通常我们会使用x-shell.putty.MobaXterm等支持ssh连接的工具去登录服务器进行管理,而执行ssh命令.scp命令等从一台服务器登录另外一台服务器的时候,通常需要 ...

  4. 2018阿里前端 - 认真写下阿里的面筋,祝福大家收到满意的offer(前端向)

    作者:叮!阿里offer请查收!链接:https://www.nowcoder.com/discuss/102509来源:牛客网 首先表达一下对阿里面试官的感谢,以及大公司的气魄——没有因为不是科班出 ...

  5. ELKBR部署检测项目日志

    ELK filebeat:具有日志收集功能,相比logstash,+filebeat更轻量,占用资源更少,适合客户端使用. redis消息队列选型:Redis 服务器通常都是用作 NoSQL 数据库, ...

  6. 美团集群调度系统HULK技术演进

    本文根据美团基础架构部/弹性策略团队负责人涂扬在2019 QCon(全球软件开发大会)上的演讲内容整理而成.本文涉及Kubernetes集群管理技术,美团相关的技术实践可参考此前发布的<美团点评 ...

  7. Net基础篇_学习笔记_第十一天_面向对象(构造函数)

    VS封装字段快捷键: 提取方法 Ctrl+R,M         封装字段 Ctrl+R,E           提取接口 Ctrl+R,I. 构成函数: public Student() { Con ...

  8. Imageio: 'ffmpeg-win32-v3.2.4.exe' was not found on your computer; downloading it now.

    场景 在使用pip下载了Imageio之后,需要下载ffmpeag-win-32-v3.2.4.exe文件,一种是在代码的 开头部分加入: imageio.plugins.ffmpeg.downloa ...

  9. 微信小程序常用的3种弹窗

    1. 表示操作成功,文字上方会显示一个表示操作成功的图标. wx.showToast({ title: '操作成功!', icon: 'success', duration: 1500 // 提示窗停 ...

  10. Cookie的获取

    1.先创建Cookie对象,设置Cookie的键和值: Cookie cookie1="); Cookie cookie2="); Cookie cookie3="); ...