使用golang插入mysql性能提升经验
前言
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性能提升经验的更多相关文章
- Mysql学习总结(38)——21条MySql性能优化经验
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情. 当我们去设计数据库表结构,对操作数 ...
- MySQL性能优化经验
核心 不做运算 md5() Order By Rand() 控制单表数据量 保持表字段苗条 平衡范式与冗余 拒绝3B Big SQL Big Transaction Big Batch 字段 用好数值 ...
- 10个提升MySQL性能的小技巧
从工作量分析到索引的三条规则,这些专家见解肯定会让您的MySQL服务器尖叫. 在所有的关系数据库中,MySQL已经被证明了完全是一头野兽,只要通知停止运行就绝对不会让你多等一秒钟,使你的应用置于困境之 ...
- paip.提升性能---mysql 性能 测试以及 参数调整.txt
paip.提升性能---mysql 性能 测试以及 参数调整.txt 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://b ...
- MySQL 8.0 —— CATS事务调度算法的性能提升
原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...
- MYSQL性能优化的最佳20+条经验
MYSQL性能优化的最佳20+条经验 2009年11月27日 陈皓 评论 148 条评论 131,702 人阅读 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数 ...
- 【转】MySQL批量SQL插入各种性能优化
原文:http://mp.weixin.qq.com/s?__biz=MzA5MzY4NTQwMA==&mid=403182899&idx=1&sn=74edf28b0bd29 ...
- 二十种实战调优MySQL性能优化的经验
二十种实战调优MySQL性能优化的经验 发布时间:2012 年 2 月 15 日 发布者: OurMySQL 来源:web大本营 才被阅读:3,354 次 消灭0评论 本文将为大家介 ...
- 使用ThinkPHP开发中MySQL性能优化的最佳21条经验
使用ThinkPHP开发中MySQL性能优化的最佳21条经验讲解,目前,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更 ...
随机推荐
- 2019 HZNU Winter Training Day 14 Comprehensive Training
A - Choosing Capital for Treeland CodeForces - 219D 题意:有一颗单向边的树,要选取一个结点作为首都.要求是这个结点到其它结点,总共需要翻转的路径数量 ...
- Codeforces Round #383 (Div. 2)D. Arpa's weak amphitheater and Mehrdad's valuable Hoses(dp背包+并查集)
题目链接 :http://codeforces.com/contest/742/problem/D 题意:给你n个女人的信息重量w和美丽度b,再给你m个关系,要求邀请的女人总重量不超过w 而且如果邀请 ...
- html/css中相对定位relative和绝对定位absolute的用法
一.相对定位(position:relative) 1.相对定位:将盒子的position属性设置为relative:可通过left.top.right.bottom设置偏移量. 相对定位基础用法示例 ...
- Python高效编程技巧实战 实战编程+面试典型问题 中高阶程序员过渡
下载链接:https://www.yinxiangit.com/603.html 目录: 如果你想用python从事多个领域的开发工作,且有一些python基础, 想进一步提高python应用能力 ...
- GC判断哪些内存需要回收
GC的问题,主要分为:1.哪些内存需要回收?2.什么时候回收?3.如何回收?这里主要讲第一个问题. 1.哪些内存需要回收? 垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”, ...
- 面试官:服务器安装 JDK 还是 JRE?可以只安装 JRE 吗?
前些日子有知友面试时被问到如题所示的问题,由于他之前没有准备到这些最最基础的知识,没有考虑过这个问题,所以被问到时竟一脸萌币,回答的不是很好.这道题主要考的是对 Java 基础知识的了解,有些同学可能 ...
- LeetCode第七题
Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have you ...
- Winforn中DevExpress的TreeList中显示某路径下的所有目录和文件(附源码下载)
场景 Winform中DevExpress的TreeList的入门使用教程(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
- SpringBoot的一个小彩蛋
彩蛋这种东西还算比较常见,在电影或者游戏里面我们也遇见过不少.今天就简单介绍一下SpringBoot里面的一个小彩蛋. 玩过SpringBoot的同志都知道,SpringBoot的启动界面是这酱紫的: ...
- sersync 实时同步
1.什么是实时同步 监控一个目录的变化, 当该目录触发事件(创建\删除\修改) 就执行动作, 这个动作可以是 rsync同步 ,也可以是其他. 2.为什么要实时同步 1.能解决nfs单点故障问题. ...