mymysql与go-mysql-driver性能比较

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

mymysql和go-mysql-driver是两个现在都很流行的go的mysql驱动,这篇文章目的是要将这两个驱动进行一下比较

两个mysql驱动的下载地址:

https://github.com/ziutek/mymysql

http://code.google.com/p/go-mysql-driver/

首先是性能测试

准备工作:

在mysql建表和初始化数据(db是test)

1
2
3
4
5
6
7
8
9
10
11
12
13
drop table if  exists admin;
 
CREATE TABLE `admin` (
     `adminid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
     `username` varchar(20) NOT NULL DEFAULT ''  COMMENT '后台用户名' ,
     `password` char(32) NOT NULL DEFAULT ''  COMMENT '密码,md5存' ,
     PRIMARY KEY(`adminid`)
)
COMMENT= '后台用户信息表'
COLLATE= 'utf8_general_ci'
ENGINE=InnoDB;
 
insert into admin set adminid=1, username= 'admin' , password= '21232f297a57a5a743894a0e4a801fc3' ;

 

两边的库代码和测试代码

Image

已经将gomysqldriver和mymysql的代码放到github上了,有兴趣的去里面看看。

https://github.com/jianfengye/MyWorks/tree/master/gomysqltest

代码里面注意的几点就是我们测试了get,insert,update三个操作,并且insert的时候不指定主键,让其自增,innodb的表,这样让mysql处理插入操作尽可能快。

 

下面运行go test -bench=".*" -v -benchmem

mymysql的表现:

Image(1)

go-mysql-driver的表现:

Image(2)

输出的数据分析:

Benchmark的测试用例名   benchtime内调用了多少次  每次调用耗时(纳秒)  每次调用耗内存  每次调用分配内存次数

比如:

mymysql 的Benchmark_getAdmin在1s内一共调用了2000次,每次调用使用了974622纳秒,使用内存大小为13444Byte,分配内存的alloc调用了220次

可以看出,go-mysql-driver的每个命令运行的时间是比mymysql多,但是内存是使用的情况却比mymysql少。

猜测原因由于go-mysql-driver是使用默认的database/sql和database/sql/driver接口,由于接口是官方提供的,估计耗时多在方法匹配上,调用内存方面由于是官方的database/sql来进行连接等分配,写的会比mymysql写的好一些。

下面比较两边的profile

在两个项目下都调用

go test -bench=".*" -c

go test -bench=".*" -cpuprofile="cpu.prof" -memprofile="mem.prof" -blockprofile="block.prof" -memprofilerate=1 -blockprofilerate=1

依次调用

go tool pprof mymysql.test cpu.prof

go tool pprof mymysql.test cpu.prof

go tool pprof mymysql.test cpu.prof

生成svg文件

具体可以参考我之前的一篇文章 go的pprof使用(http://www.cnblogs.com/yjf512/archive/2012/12/27/2835331.html

我这里已经将它们都生成好了并命名为诸如mymysql_cpu.svg放在github上,你也可以直接去下载看

https://github.com/jianfengye/MyWorks/tree/master/gomysqltest

怎么看svg

关于pprof这里有一篇权威文章:cpuprofile(http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html

 

先要明白几个名词

sample

sample就是“取样”。pprof是基于取样调查的,比如我每纳秒取样一次,收集这个时候程序的运行函数栈,知道现在是运行在那个函数中,然后把这些信息放在pprof文件中提供分析。

node

node就是函数调用信息,哪个函数中被调用了,调用了多少次

Image(3)

方法名

本方法占用sample次数(占所有sample的总数)

本方法的下行方法调用次数(占所有sample的比例)

“本方法占用sample的次数”就是除了调用下行的方法之外的其他代码占用的方法数,当然是越小越好,越小说明了除了下行的方法之外的代码几乎不占用cpu时间。node的大小和这个值是正相关的

“下行方法调用次数”就是下行方法的调用中占用了多少个sample。

如果上面两个值相等,那么“下行方法调用次数”就会被被忽略。这个一般只出现在edges中。

比如sweepspan就是下行方法占用37个sample,本身只占用了1个sample。

edges

edges就是终结点

Image(4)

runtime.mcmp就是自身是终结点,没有下行方法,所以下行和本方法占用的sample相等。

基本信息解读

比如:

Image(5)

mymysql.test是可执行文件名

Total samples:总的统计sample(打点数)

Focusing on:关注的sample。为什么有关注sample这么一说呢,并不是说所有的node和edges都是有用的信息,有的不重要的node和edges是会被忽略的。Focusing on samples就是除了这些不重要的node和edges之外的sample。

Dropped nodes:参考Focusing on。被忽略的node。

Dropped edges: 参考Focusing on。被忽略的edges。

ps: 这里默认的total sample是等于focusing sample的。你在pprof的时候可以使用--ignore参数来忽略掉那些不重要的node或者edges

明白了这些就知道了,看图应该从最大的node往小的方向看,分析下占用资源多的函数在那里,是否可以优化这个函数或者方法。

 

比如可以看一下

gomysqldriver_cpu.svg这个例子

它有个比较占用sample的分支是

Image(6)

它的源头在parseDSN

看到代码里面去,会发现是解析dsn这步的时候使用了正则,导致运行Open的时候运行速度下降了。

所以说如果parseDSN这个函数的参数不是dsn string,而是使用map直接指定username,password等,这里的速度就会上去了。当然这其实也是不可以的,因为database/sql/driver的Open方法定义的参数就是一个string。

总结:

pprof图将代码流程完完全全地展现在我们面前。所以说呢我们可以做这么几件事情:

1 根据pprof优化代码

2 根据pprof学习一个完全陌生的开源软件

3 根据pprof学习go的一个程序是怎么运行的

4 项目上线前的性能测试和压力测试(在ab之外的有一个好的选择了)

mymysql和go-mysql-driver的测试总结

根据以上的比较,我还是倾向于使用go-mysql-driver。原因有几个:

1 go-mysql-driver是实现了golang标准库database/sql的产物。底层实现比较有保证

2 go-mysql-driver虽然每个命令的运行时间比mymysql长,但是内存使用少得非常明显,这点两方算打平。

3 go-mysql-driver实现了database/sql,如果数据库换成其他的话,不需要更改应用逻辑的代码。

4 go-mysql-driver实现了database/sql,这个接口的设计也是非常好的,基本和php中的pdo一样,上手和学习成本低。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
go如何使用SQLX操作MySQL数据库?
sqlx是Go语言中一款流行的第三方数据库操作包,它扩展了Go标准库`database/sql`的功能,极大地简化了数据库操作流程并提供了丰富的数据库交互方法。
|
29天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
39 4
|
6月前
|
SQL 关系型数据库 MySQL
go 通过sql操作mysql
go 通过sql操作mysql
32 1
|
3月前
|
关系型数据库 MySQL Go
go抽取mysql配置到yaml配置文件
go抽取mysql配置到yaml配置文件
|
7月前
|
SQL 关系型数据库 MySQL
【Go语言专栏】使用Go语言连接MySQL数据库
【4月更文挑战第30天】本文介绍了如何使用Go语言连接和操作MySQL数据库,包括选择`go-sql-driver/mysql`驱动、安装导入、建立连接、执行SQL查询、插入/更新/删除操作、事务处理以及性能优化和最佳实践。通过示例代码,展示了连接数据库、使用连接池、事务管理和性能调优的方法,帮助开发者构建高效、稳定的Web应用。
1305 0
|
4月前
|
SQL 关系型数据库 MySQL
Go语言中使用 sqlx 来操作 MySQL
Go语言因其高效的性能和简洁的语法而受到开发者们的欢迎。在开发过程中,数据库操作不可或缺。虽然Go的标准库提供了`database/sql`包支持数据库操作,但使用起来稍显复杂。为此,`sqlx`应运而生,作为`database/sql`的扩展库,它简化了许多常见的数据库任务。本文介绍如何使用`sqlx`包操作MySQL数据库,包括安装所需的包、连接数据库、创建表、插入/查询/更新/删除数据等操作,并展示了如何利用命名参数来进一步简化代码。通过`sqlx`,开发者可以更加高效且简洁地完成数据库交互任务。
37 1
|
4月前
|
SQL 关系型数据库 MySQL
Go语言中如何连接 MySQL,基础必备!
在现代应用中,数据库操作至关重要。本教程将指导你使用Go语言进行MySQL的CRUD操作。首先,确保已创建`test_db`数据库及`users`表。接着安装MySQL驱动:`go get -u github.com/go-sql-driver/mysql`。通过示例代码,你将学会连接数据库、创建、查询、更新及删除用户记录。尽管此方法直接,但在实际项目中可能略显繁琐,后续会介绍更高效的库如sqlx或gorm。现在,让我们从基础开始,掌握Go语言中的数据库交互技巧。
64 3
|
4月前
|
SQL 安全 关系型数据库
Go 语言中的 MySQL 事务操作
在现代应用中,确保数据完整与一致至关重要。MySQL的事务机制提供了可靠保障。本文首先解释了事务的概念及其ACID特性,随后介绍了如何在Go语言中使用`database/sql`包进行MySQL事务操作。通过一个银行转账的例子,演示了如何通过Go开启事务、执行操作并在必要时回滚或提交,确保数据一致性。最后,还讨论了不同事务隔离级别的含义及如何在Go中设置这些级别。通过本文的学习,开发者能更好地掌握MySQL事务的应用。
55 0
|
4月前
|
SQL 关系型数据库 MySQL
Go语言中进行MySQL预处理和SQL注入防护
在现代Web应用开发中,安全性至关重要。SQL注入是一种常见的攻击方式,攻击者可通过构造特殊SQL查询来非法访问或修改数据库数据。本文介绍如何利用Go语言中的预处理SQL语句来防范此类攻击。预处理不仅能提升安全性,还能提高性能并简化代码。通过使用`?`作为占位符,Go自动处理参数转义,有效避免SQL注入。此外,文章还提供了连接MySQL数据库、执行预处理查询以及最佳实践的示例代码。务必遵循这些指导原则,确保应用程序的安全性。
114 0
|
4月前
|
SQL 关系型数据库 MySQL
【go笔记】使用sqlx操作MySQL
【go笔记】使用sqlx操作MySQL