解决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 相关文章推荐
Trying to clone an uncloneable object of class Imagic的解决方法
Jan 11 PHP
PHP中全面阻止SQL注入式攻击分析小结
Jan 30 PHP
用PHP实现Ftp用户的在线管理
Feb 16 PHP
百度工程师讲PHP函数的实现原理及性能分析(一)
May 13 PHP
php实现多城市切换特效
Aug 09 PHP
PHP表单数据写入MySQL数据库的代码
May 31 PHP
PHP+JQuery+Ajax实现分页方法详解
Aug 06 PHP
php实现图片以base64显示的方法
Oct 13 PHP
[原创]PHP实现字节数Byte转换为KB、MB、GB、TB的方法
Aug 31 PHP
PHPUnit测试私有属性和方法功能示例
Jun 12 PHP
php实现等比例压缩图片
Jul 26 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 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 array_map array_multisort 高效处理多维数组排序
2009/06/11 PHP
PHP学习笔记之二
2011/01/17 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
Windows服务器中PHP如何安装redis扩展
2019/09/27 PHP
初学JavaScript_03(ExtJs Grid的简单使用)
2008/10/02 Javascript
JavaScript isPrototypeOf和hasOwnProperty使用区别
2010/03/04 Javascript
JSON序列化与解析原生JS方法且IE6和chrome测试通过
2013/09/05 Javascript
利用js动态添加删除table行的示例代码
2013/12/16 Javascript
Js表格万条数据瞬间加载实现代码
2014/02/20 Javascript
5款JavaScript代码压缩工具推荐
2014/07/07 Javascript
javascript 回调函数详解
2014/11/11 Javascript
nodejs教程之入门
2014/11/21 NodeJs
JavaScript中window.showModalDialog()用法详解
2014/12/18 Javascript
JavaScript面向对象之私有静态变量实例分析
2016/01/14 Javascript
jQuery AjaxUpload 上传图片代码
2016/02/02 Javascript
jQuery实现的导航下拉菜单效果
2016/07/04 Javascript
JavaScript中子对象访问父对象的方式详解
2016/09/01 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
Angular实现购物车计算示例代码
2017/02/21 Javascript
关于Google发布的JavaScript代码规范你要知道哪些
2018/04/04 Javascript
Javascript获取某个月的天数
2018/05/30 Javascript
使用weixin-java-tools完成微信授权登录、微信支付的示例
2018/09/26 Javascript
基于Angular 8和Bootstrap 4实现动态主题切换的示例代码
2020/02/11 Javascript
JS出现404错误原理及解决方案
2020/07/01 Javascript
[01:33:25]DOTA2-DPC中国联赛 正赛 Elephant vs IG BO3 第一场 1月24日
2021/03/11 DOTA
python学习教程之Numpy和Pandas的使用
2017/09/11 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
python 回溯法模板详解
2020/02/26 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
2021/02/04 Python
专科文秘应届生求职信
2013/11/18 职场文书
服装公司总经理岗位职责
2013/11/30 职场文书
校园之声广播稿
2014/01/31 职场文书
湖南省召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
大学团日活动总结书
2015/05/11 职场文书
详解RedisTemplate下Redis分布式锁引发的系列问题
2021/04/27 Redis