解决PHP里大量数据循环时内存耗尽的方法


Posted in PHP onOctober 10, 2015

最近在开发一个PHP程序的时候遇到如下一问题:

PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted

错误信息显示允许的最大内存已经耗尽。遇到这样的错误起初让我很诧异,但转眼一想,也不奇怪,因为我正在开发的这个程序是要用一个foreach循环语句在一个有4万条记录的表里全表搜索具有特定特征的数据,也就是说,一次要把4万条数据取出,然后逐条检查每天数据。可想而知,4万条数据全部加载到内存中,内存不爆才怪。

 解决PHP里大量数据循环时内存耗尽的方法

毕竟编程这么多年,我隐约记得PHP里提供有非一次全部加载数据的API,是像处理流媒体那样,随用随取随丢、数据并不会积累在内存的查询方法。经过简单的搜索,果然在官方网站上找到的正确的用法。

这个问题在PHP的官方网站上叫缓冲查询和非缓冲查询(Buffered and Unbuffered queries)。 PHP的查询缺省模式是缓冲模式。也就是说,查询数据结果会一次全部提取到内存里供PHP程序处理。这样给了PHP程序额外的功能,比如说,计算行数,将 指针指向某一行等。更重要的是程序可以对数据集反复进行二次查询和过滤等操作。但这种缓冲查询模式的缺陷就是消耗内存,也就是用空间换速度。

相对的,另外一种PHP查询模式是非缓冲查询,数据库服务器会一条一条的返回数据,而不是一次全部返回,这样的结果就是PHP程序消耗较少的内存,但却增加了数据库服务器的压力,因为数据库会一直等待PHP来取数据,一直到数据全部取完。

很显然,缓冲查询模式适用于小数据量查询,而非缓冲查询适应于大数据量查询。

对于PHP的缓冲模式查询大家都知道,下面列举的例子是如何执行非缓冲查询API。

非缓冲查询方法一: mysqli

<?php 
$mysqli = new mysqli("localhost", "my_user", "my_password", "world"); 
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); 
if ($uresult) { 
  while ($row = $uresult->fetch_assoc()) { 
    echo $row['Name'] . PHP_EOL; 
  } 
} 
$uresult->close(); 
?>

非缓冲查询方法二: pdo_mysql

<?php 
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); 
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); 

$uresult = $pdo->query("SELECT Name FROM City"); 
if ($uresult) { 
  while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { 
    echo $row['Name'] . PHP_EOL; 
  } 
} 
?>

非缓冲查询方法三: mysql

<?php 
$conn = mysql_connect("localhost", "my_user", "my_pass"); 
$db  = mysql_select_db("world"); 

$uresult = mysql_unbuffered_query("SELECT Name FROM City"); 
if ($uresult) { 
  while ($row = mysql_fetch_assoc($uresult)) { 
    echo $row['Name'] . PHP_EOL; 
  } 
} 
?>

以上内容就是小编给大家分享的解决PHP里大量数据循环时内存耗尽的方法,希望对大家有所帮助。

PHP 相关文章推荐
如何获得PHP相关资料
Oct 09 PHP
解析:使用php mongodb扩展时 需要注意的事项
Jun 18 PHP
PHP实现获取FLV文件的时间
Feb 10 PHP
php简单实现多字节字符串翻转的方法
Mar 31 PHP
使用Appcan客户端自动更新PHP版本号(全)
Jul 31 PHP
thinkphp框架下实现登录、注册、找回密码功能
Apr 06 PHP
PHP 验证身份证是否合法的函数
Feb 09 PHP
ThinkPHP下表单令牌错误与解决方法分析
May 20 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
Nov 17 PHP
实例讲解php实现多线程
Jan 27 PHP
laravel邮件发送的实现代码示例
Jan 31 PHP
php中删除、清空session的方式总结
Oct 09 #PHP
[原创]ThinkPHP让../Public在模板不解析(直接输出)的方法
Oct 09 #PHP
PHP中Closure类的使用方法及详解
Oct 09 #PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
Oct 09 #PHP
PHP程序员不应该忽略的3点
Oct 09 #PHP
PHP+jQuery+Ajax实现分页效果 jPaginate插件的应用
Oct 09 #PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
Oct 08 #PHP
You might like
深入解析php模板技术原理【一】
2008/01/10 PHP
PHP OPCode缓存 APC详细介绍
2010/10/12 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
基于thinkPHP实现的微信自定义分享功能示例
2016/09/23 PHP
PHP7 新增功能
2021/03/09 PHP
在线游戏大家来找茬II
2006/09/30 Javascript
JavaScript之编码规范 推荐
2012/05/23 Javascript
jquery下checked取值问题的解决方法
2012/08/09 Javascript
使用不同的方法结合/合并两个JS数组
2014/09/18 Javascript
js实现可得到不同颜色值的颜色选择器实例
2015/02/28 Javascript
JS跨域解决方案之使用CORS实现跨域
2016/04/14 Javascript
Angular4 ElementRef的应用
2018/02/26 Javascript
vue使用监听实现全选反选功能
2018/07/06 Javascript
浅谈js中的bind
2019/03/18 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
基于webpack4+vue-cli3项目实现换肤功能
2019/07/17 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
2019/08/02 Javascript
使用webpack搭建vue环境的教程详解
2019/12/31 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
Python备份目录及目录下的全部内容的实现方法
2016/06/12 Python
python3 爬取图片的实例代码
2018/11/06 Python
浅谈python函数调用返回两个或多个变量的方法
2019/01/23 Python
Python匿名函数/排序函数/过滤函数/映射函数/递归/二分法
2019/06/05 Python
pip指定python位置安装软件包的方法
2019/07/12 Python
Django 项目重命名的实现步骤解析
2019/08/14 Python
python flask中动态URL规则详解
2019/11/22 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
django 实现手动存储文件到model的FileField
2020/03/30 Python
keras 回调函数Callbacks 断点ModelCheckpoint教程
2020/06/18 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
HTML5 Canvas像素处理使用接口介绍
2012/12/02 HTML / CSS
Daisy London官网:英国最大的首饰集团IBB旗下
2019/02/28 全球购物
Ado与Ado.net的相同与不同
2014/12/08 面试题
民族学专业求职信
2014/07/28 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
趣味运动会加油词
2015/07/18 职场文书