解决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实现长连接的方法与注意事项的问题
May 10 PHP
php字符串截取的简单方法
Jul 04 PHP
Win下如何安装PHP的APC拓展
Aug 07 PHP
php5.3 goto函数介绍和示例
Mar 21 PHP
php读取大文件示例分享(文件操作类)
Apr 13 PHP
浅谈thinkphp的实例化模型
Jan 04 PHP
Laravel中使用阿里云OSS Composer包分享
Feb 10 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
Dec 14 PHP
thinkphp3.2点击刷新生成验证码
Feb 16 PHP
PHP中PDO的事务处理分析
Apr 07 PHP
微信红包随机生成算法php版
Jul 21 PHP
PHP实现数组的笛卡尔积运算示例
Dec 15 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
Discuz!5的PHP代码高亮显示插件(黑暗中的舞者更新)
2007/01/29 PHP
PHP is_subclass_of函数的一个BUG和解决方法
2014/06/01 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
php错误日志简单配置方法
2016/07/11 PHP
php创建多级目录与级联删除文件的方法示例
2019/09/12 PHP
通用JS事件写法实现代码
2009/01/07 Javascript
prototype与jquery下Ajax实现的差别
2009/09/13 Javascript
Extjs中DisplayField的日期或者数字格式化扩展
2010/09/03 Javascript
灵活应用js调试技巧解决样式问题的步骤分享
2012/03/15 Javascript
游览器中javascript的执行过程(图文)
2012/05/20 Javascript
深入理解javascript中defer的作用
2013/12/11 Javascript
jquery实现图片翻页效果
2013/12/23 Javascript
jquery中常用的函数和属性详细解析
2014/03/07 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
Jquery为DIV添加click事件的简单实例
2016/06/02 Javascript
jQuery实现每隔几条元素增加1条线的方法
2016/06/27 Javascript
想学习javascript JS和jQuery哪个重要 先学哪个
2016/12/11 Javascript
Vue点击切换颜色的方法
2018/09/13 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
详解JavaScript之ES5的继承
2020/07/08 Javascript
[52:02]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第二场 2月26日
2021/03/11 DOTA
Python获取Windows或Linux主机名称通用函数分享
2014/11/22 Python
Python递归及尾递归优化操作实例分析
2020/02/01 Python
Python实现自动整理文件的脚本
2020/12/17 Python
英国网上购买门:Direct Doors
2018/06/07 全球购物
Chantelle仙黛尔内衣美国官网:法国第一品牌内衣
2018/07/26 全球购物
美国眼镜网站:LensCrafters
2020/01/19 全球购物
百度JavaScript笔试题
2015/01/15 面试题
酒吧创业计划书
2014/01/18 职场文书
有兼职工作经历的简历自我评价
2014/03/07 职场文书
辩论赛主持词
2014/03/18 职场文书
学校安全管理责任书
2014/07/23 职场文书
搞笑婚庆主持词
2015/06/29 职场文书
银行文明优质服务培训心得体会
2016/01/09 职场文书
致男子1500米运动员的广播稿
2019/11/08 职场文书