PHP优化之批量操作MySQL实例分析


Posted in PHP onApril 23, 2020

本文实例讲述了PHP优化之批量操作MySQL。分享给大家供大家参考,具体如下:

设计一个数据表如下:

create table optimization(
  id INT NOT NULL AUTO_INCREMENT,
  value VARCHAR(10) NOT NULL,
  PRIMARY KEY(id)
);

现在有一个业务需求需要批量插入数据。

先来看看下面这一段代码:

<?php
  $dsn = 'mysql:dbname=test;host=127.0.0.1';
  $user = 'root';
  $password = 'root';

  try {
    $dbh = new PDO($dsn, $user, $password);
  } catch(PDOException $e) {
    echo 'Connection failed: ' , $e->getMessage();
  }
  $begin = microtime(true) * 1000;

  $count = 100;
  $stmt = $dbh->prepare('INSERT INTO `optimization` (id, value) VALUES(:id, :value)');
  $stmt->bindParam(':id', $id);
  $stmt->bindParam(':value', $value);
  for ($i = 0; $i < $count; $i++)
  {
    $id = '';
    $value = $i;
    $stmt->execute();
  }

  $end = microtime(true) * 1000;
  echo 'excuted : ' , ($end - $begin) , ' ms';

经过测试,上面代码运行结果如下:

1、excuted : 7601.4348144531 ms

2、excuted : 7476.4270019531 ms

3、excuted : 7674.4387207031 ms

平均:7584.100179036433 ms

再来看看第二段代码:

<?php
  $dsn = 'mysql:dbname=test;host=127.0.0.1';
  $user = 'root';
  $password = 'root';

  try {
    $dbh = new PDO($dsn, $user, $password);
  } catch(PDOException $e) {
    echo 'Connection failed: ' , $e->getMessage();
  }

  $begin = microtime(true) * 1000;
  $dbh->beginTransaction();
  try {
    $count = 100;
    $sql = 'INSERT INTO `optimization` (id, value) VALUES ';
    $sql_arr = array();
    $sql_str = '';
    for ($i = 0; $i < $count; $i++)
    {
      $sql_arr[] = ("('', $i)");
    }
    $sql_str = implode(',', $sql_arr);
    $sql .= $sql_str;
    $stmt = $dbh->prepare($sql);
    $stmt->execute();
    $dbh->commit();
  } catch(Exception $e) {
    $dbh->rollBack();
    echo $e->getMessage() . '<br>';
  }

  $end = microtime(true) * 1000;
  echo 'excuted : ' , ($end - $begin) , ' ms';

上面这段代码的运行结果如下:

1、excuted : 99.005859375 ms

2、excuted : 103.00610351562 ms

3、excuted : 68.00390625 ms

平均:90.00528971354 ms

##分析 可以看出,在第二段代码中,使用了批量插入,此时的效率比第一段提高了84%。原因如下:

  • 使用第一段代码的时候,因为每一次循环里都执行了一个mysql语句,此时php需要与mysql获得连接,然后再执行mysql语句,然后再断开。这就是第一段代码最主要的时间开销?PHP与MySQL连接的网络传输IO
  • 第一段代码SQL语句解析的次数更多

因此,在第二段代码中,通过合并SQL语句来实现减少SQL语句解析的次数以及PHP与MySQL连接的次数来达到减少网络传输IO的开销。

注意: 1、SQL语句是有长度限制的,因此,在进行SQL语句合并时务必不能超过SQL长度限制,通过设置max_allowed_packet可以修改,默认是1M,测试时修改为8M。

##总结

在进行对数据库的批量操作(如:插入、更新、修改)时,应当尽可能将SQL语句合并后再执行而不是在循环中依次执行。

记录下最近在项目中犯下的一个比较大的错误,以后不能再犯了。以前一直都没有注意到,直到现在真正参与到企业项目中,自己的代码被老大指出错误后才发现自己的错误。学习了。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
我的论坛源代码(二)
Oct 09 PHP
php错误提示failed to open stream: HTTP request failed!的完美解决方法
Jun 06 PHP
解析thinkphp中的导入文件标签
Jun 20 PHP
CURL状态码列表(详细)
Jun 27 PHP
php 生成自动创建文件夹并上传文件的示例代码
Mar 07 PHP
thinkphp特殊标签用法概述
Nov 24 PHP
php计算给定时间之前的函数用法实例
Apr 03 PHP
php计算到指定日期还有多少天的方法
Apr 14 PHP
PHP实现XML与数据格式进行转换类实例
Jul 29 PHP
Thinkphp微信公众号支付接口
Aug 04 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
Oct 16 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 20 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
Apr 23 #PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
Apr 23 #PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
Apr 23 #PHP
Thinkphp 框架扩展之数据库驱动常用方法小结
Apr 23 #PHP
Thinkphp 框架扩展之类库扩展操作详解
Apr 23 #PHP
TP框架实现上传一张图片和批量上传图片的方法分析
Apr 23 #PHP
php实现将数组或对象写入到文件的方法小结【三种方法】
Apr 22 #PHP
You might like
php中计算时间差的几种方法
2009/12/31 PHP
基于php socket(fsockopen)的应用实例分析
2013/06/02 PHP
php strrpos()与strripos()函数
2013/08/31 PHP
PHP实现链式操作的核心思想
2015/06/23 PHP
PHP基于IMAP收取邮件的方法示例
2017/08/07 PHP
ThinkPHP框架整合微信支付之Native 扫码支付模式一图文详解
2019/04/09 PHP
php连接mysql之mysql_connect()与mysqli_connect()的区别
2020/07/19 PHP
兼容IE和Firefox的javascript获取iframe文档内容的函数
2011/08/15 Javascript
DIV+CSS+JS不间断横向滚动实现代码
2013/03/19 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
Node.js中使用jQuery的做法
2016/08/17 Javascript
Vue2实时监听表单变化的示例讲解
2018/08/30 Javascript
OpenLayer学习之自定义测量控件
2020/09/28 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
[05:04]完美世界携手游戏风云打造 卡尔工作室地图界面篇
2013/04/23 DOTA
python 布尔操作实现代码
2013/03/23 Python
使用Python的Tornado框架实现一个简单的WebQQ机器人
2015/04/24 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
Django+uni-app实现数据通信中的请求跨域的示例代码
2019/10/12 Python
Python使用psutil获取进程信息的例子
2019/12/17 Python
简单了解python字符串前面加r,u的含义
2019/12/26 Python
python代码如何实现余弦相似性计算
2020/02/09 Python
python使用for...else跳出双层嵌套循环的方法实例
2020/05/17 Python
Django中F函数的使用示例代码详解
2020/07/06 Python
Jabra捷波朗美国官网:用于办公、车载和运动的无线蓝牙耳麦
2017/02/01 全球购物
瑞典灯具和照明网上商店:Lamp24.se
2018/03/17 全球购物
Fanatics法国官网:美国体育电商
2019/08/27 全球购物
将一个数的从第5位开始的7个数取出,其余位置0
2016/05/26 面试题
大学四年学习的自我评价分享
2013/12/09 职场文书
生日宴会答谢词
2014/01/09 职场文书
树转促学习心得体会
2014/09/10 职场文书
2014年协会工作总结
2014/11/22 职场文书
小学英语教师2015年度个人工作总结
2015/10/14 职场文书
eclipse创建项目没有dynamic web的解决方法
2021/06/24 Java/Android
Mongo服务重启异常问题的处理方法
2021/07/01 MongoDB
win10搭建配置ftp服务器的方法
2022/08/05 Servers