2019独角兽企业重金招聘Python工程师标准>>>

测试环境

配置直接影响执行速度,先上一下测试机配置:

  • cpu i7 5500U(低电压伤不起,以后再也不买低电压的U了)
  • 内存 8G ddr3 1600
  • php 7.1
  • mysql 5.5.40
  • 开发框架 CodeIgniter 3.1.2

影响写入效率的因素都有什么?

  • 数据库引擎

开发中常用的数据库引擎 MyISAM,InnoDB 这两种,其他的数据库引擎我在开发中还没用到,所以不在这里测试了。

先看一下库表结构 :

test库下有两张表:分别为上面提的两种引擎:

每张表结构如下(一个自增id,一个varchar类型待插入字段):

缺省状态下对两表插入20w数据看一下效率:

PHP代码如下:

/*** * 测试插入效率* * @return void* */public function insertTest(){set_time_limit(0);   //防止超300s 500错误$t1 = microtime(true);//随机插入num条for ($i=1; $i<=200000; $i++){$result = $this->db->insert('myisam', ['value' => uniqid().$i]);}//程序运行时间$t2 = microtime(true);echo '耗时:'.round($t2-$t1,3).'秒<br>';echo '内存消耗:'.round(memory_get_usage()/1048576,2)." M<br/>";}

执行结果:

20w 数据 Myisam要 接近3分钟了。

看一下InnoDb缺省状态下执行时间:

插入1w条数据 用了 6分49秒,没办法等下去了, 按照这个数据量推测 6分49 * 20 = ???

后期由于数据量增多,也会影响插入性能,所以InnoDb默认状态插入20w单字段数据要2小时以上,无法     忍受。

  • 业务逻辑

显然上面的业务逻辑是有问题的,每条数据单次插入,增加了mysql的开销,每次插入数据都要重新连         接一下mysql,肯定是相当浪费资源了。所以CI提供了 insert_batch(),批量写入数据。Thinkphp3.2         也有addAll() 这样的方法来支持。其他框架应该都有!

原理很简单就是把二维数组,拼接为sql

将单条Sql如下:

$sql = "INSERT INTO TEST (value) VALUES ('helloworld1')";

$sql = "INSERT INTO TEST (value) VALUES ('helloworld2')";

拼接为:

$sql = "INSERT INTO TEST (value) VALUES ('helloworld1'), ('helloworld2')";

很明显批量插入速度要快很多。

还是20w数据,MyISAM 下批量查询速度多快?(已有数据会影响插入效率,已清空 myisam表)

还是上代码

/*** * 测试批量插入效率* * @return void* @author lidalin.se@gmail.com* */public function insertTest(){set_time_limit(0);   //防止超300s 500错误$t1 = microtime(true);//随机插入num条for ($i=1; $i<=200000; $i++){$data[$i] = ['value' => uniqid().$i];}//程序运行时间$t2 = microtime(true);echo '循环耗时:'.round($t2-$t1,3).'秒<br>';$this->db->insert_batch('myisam', $data);  //批量插入$t3 = microtime(true);echo '插入耗时:'.round($t3-$t2,3).'秒<br>';echo '内存消耗:'.round(memory_get_usage()/1048576,2)." M<br/>";}

执行结果:

比起之前的167秒的单条插入速度快了 5 倍。内存消耗增加1.5倍左右,内存换时间,可取~~~

InnoDB 会是什么速度呢?

执行结果:

这次终于执行完了,而且速度很快。和之前的两个小时比,效率也提升了N倍。

  • 修改配置参数提升性能:

InnoDB 引擎 真的这么慢?这么low?

答案显然是:NO

InnoDB写入之所以这么慢的一个原因是:

innodb_flush_log_at_trx_commit

        参数配置的问题

如下图默认的值:

关于值请查阅mysql文档:

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html

innodb_flush_log_at_trx_commit=0时, log buffer将每秒一次地写入log file, 并且log file的flush(刷新          到disk)操作同时进行. 此时, 事务提交是不会主动触发写入磁盘的操作.

innodb_flush_log_at_trx_commit=1时(默认), 每次事务提交时, MySQL会把log buffer的数据写入log f          ile, 并且将log file flush(刷新到disk)中去.

innodb_flush_log_at_trx_commit=2时, 每次事务提交时, MySQL会把log buffer的数据写入log file, 但          不会主动触发flush(刷新到disk)操作同时进行. 然而, MySQL会每秒执行一次flush(刷新到disk)操作.

把值设置为2,再试一下:

速度又提升了 3倍,和 MyISAM几乎相同。

所以以后说InnoDB写入速度慢,可能是配置问题

  • 还可以优化?

还有什么可以优化?

由于我们使用了 框架的insert_batch,看一下CI源码:

/*** The "set_insert_batch" function.  Allows key/value pairs to be set for batch inserts** @param mixed* @param  string* @param bool* @return  CI_DB_query_builder*/public function set_insert_batch($key, $value = '', $escape = NULL){$key = $this->_object_to_array_batch($key);if ( ! is_array($key)){$key = array($key => $value);}is_bool($escape) OR $escape = $this->_protect_identifiers;$keys = array_keys($this->_object_to_array(current($key)));sort($keys);foreach ($key as $row){$row = $this->_object_to_array($row);if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0){// batch function above returns an error on an empty array$this->qb_set[] = array();return;}ksort($row); // puts $row in the same order as our keysif ($escape !== FALSE){$clean = array();foreach ($row as $value){$clean[] = $this->escape($value);}$row = $clean;}$this->qb_set[] = '('.implode(',', $row).')';}foreach ($keys as $k){$this->qb_keys[] = $this->protect_identifiers($k, FALSE, $escape);}return $this;}

我们传入的数据,方法会再循环,判断。所以建议语句自己拼接

代码修改如下:

/*** * 测试插入效率* * @return void* @author lidalin.se@gmail.com* */public function insertTest(){set_time_limit(0);   //防止超300s 500错误$t1 = microtime(true);$sql = "insert into innodb (value) VALUES";//随机插入num条for ($i=1; $i<=200000; $i++){$val = uniqid().$i;$sql .= "('{$val}'),";}$sql = substr($sql,0,-1);//程序运行时间$t2 = microtime(true);echo '循环耗时:'.round($t2-$t1,3).'秒<br>';$this->db->query($sql);  //批量插入$t3 = microtime(true);echo '插入耗时:'.round($t3-$t2,3).'秒<br>';echo '内存消耗:'.round(memory_get_usage()/1048576,2)." M<br/>";}

执行结果:

20W条数据  InnoDB   循环1.6秒,插入1.2秒。速度是不是很爽了。。

拼接语句可能会报错
设置一下

max_allowed_packet = 500M

允许mysql 接受数据包大小。

欢迎转载:

转载请注明:https://my.oschina.net/famoustone/blog/856736

转载于:https://my.oschina.net/famoustone/blog/856736

Mysql 批量写入数据 性能优化相关推荐

  1. Mysql批量插入更新性能优化

    Mysql批量插入更新性能优化 对于数据量较大的插入和更新,因io/cpu等性能瓶颈,会产生大量的时间消耗,目前主流的优化主要包括预编译.单条sql插入多条数据.事务插入等,下面详细介绍一下: 单条插 ...

  2. 转载--批量更新数据(性能优化)

    最近做的游戏,上线后出了不少问题,所以我就经常去查数据库数据,翻各种日志等,但是在查询的时候发现好蛋疼,有些地方的时间是写 "2016-08-11 20:13:02"这种格式,有些 ...

  3. MySQL批量SQL插入性能优化

    注意事项: 1. SQL语句是有长度限制,在进行数据合并在同一SQL中务必不能超过SQL长度限制,通过max_allowed_packet配置可以修改,默认是1M,测试时修改为8M. 2. 事务需要控 ...

  4. mysql 大量写入 优化_MYSQL大批量写入之性能优化

    大家提到Mysql的性能优化都是注重于优化sql以及索引来提升查询性能,大多数产品或者网站面临的更多的高并发数据读取问题.然而在大量写入数据场景该如  何优化呢? 今天这里主要给大家介绍,在有大量写入 ...

  5. Mysql批量插入数据问题解决和优化

    Mysql批量插入数据问题解决和优化 一.问题描述 项目中mysql批量插入大概50000左右数据,使用事务和批量,但是速度依旧很慢,大约60s左右,迫切希望改进这个问题. 二.问题原因 尽管是批量a ...

  6. 读薄《高性能MySql》(四)查询性能优化

    读薄<高性能MySql>(一)MySql基本知识 读薄<高性能MySql>(二)Scheme与数据优化 读薄<高性能MySql>(三)索引优化 读薄<高性能M ...

  7. EF Core 批量写入数据使用整理_EF Core批量插入数据(一)

    一.EF Core 批量添加数据 问题详解 AddRange() 问题整理: 1.对于批量写入数据,每次几万条情况 使用 Add() 方法不合理 2.使用AddRange() 每次批量写入数据也要有个 ...

  8. MySQL基于冷热数据分离优化的LRU刷盘策略

    MySQL基于冷热数据分离优化的LRU刷盘策略 前言 对于计算机刷盘这个概念相信大家都非常熟悉了,刷盘策略,其实在操作系统层面来说的话就是页面置换算法. 不知道各位朋友们还记得页面置换算法有哪些吗? ...

  9. 【性能优化】MySQL 数据库连接原理和性能优化 - 学习/实践

    1.应用场景 学习MySQL数据库连接原理和性能优化, 开发高性能程序. 2.学习/操作 1. 文档阅读 MySQL 数据库连接原理和性能优化 - 高性能 MySQL 实战 | Laravel 学院 ...

最新文章

  1. Asp.net Dynamic Data之三改变编辑和操作数据的现实方式
  2. python函数小练习
  3. bzoj4316: 小C的独立集
  4. C语言 do while 和 while 循环 - C语言零基础入门教程
  5. java怎样才算高级_怎样才算是一名java高手?
  6. linux6.0设置共享文件夹,[原创] how to virtualbox sharefolder共享文件夹(数据空间)设置全记录...
  7. IHttpModule与IHttpHandler的区别整理
  8. 文本生成解码策略笔记-常见解码策略
  9. idea最近svn提交很慢 idea中svn提交时performing vcs refresh时间很长
  10. springboot批量更新实体_springboot使用druid批量更新报错
  11. 第一台计算机 采用工 作原理,第1讲计算机工作原理模版课件.ppt
  12. 微信小程序文字语音转换/中英文自动翻译
  13. web端接入QQ第三方登陆获取本地QQ登陆信息流程
  14. 2020下半年新机最新消息_别买新机了!2020下半年手机居然这么强……
  15. mysql mod如何使用_MySQL MOD()用法及代码示例
  16. 如何关闭计算机服务检测,电脑知识:Win7系统如何关闭交互式服务检测窗口?...
  17. 7-2 买电影票 (C语言)
  18. java字符串转日期_在java中如何将一个字符串转换为日期?
  19. [Jzoj] 3426. 封印一击
  20. vue---父组件实时取到子元素的v-model

热门文章

  1. ReactOS 0.0.21从开机启动,到加载驱动的过程
  2. html5中的dom中的各种节点的层次关系是怎样的
  3. buildroot mysql
  4. 基于DDD的.NET开发框架 - ABP缓存Caching实现
  5. 检测msmq里消息的数量
  6. 俄罗斯方块新增行算法:不拘一格编程序之二
  7. 最全面的_Redis_基本操作总结
  8. 11.23关于微信JSAPI缺少参数的问题解决
  9. 小程序~WeUI下载使用
  10. 六、jQuery基础