解决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 相关文章推荐
实现分十页分向前十页向后十页的处理
Oct 09 PHP
我的论坛源代码(十)
Oct 09 PHP
PHP $_SERVER详解
Jan 16 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
Oct 08 PHP
CI(CodeIgniter)框架配置
Jun 10 PHP
可以保证单词完整性的PHP英文字符串截取代码分享
Jul 15 PHP
php获取、检查类名、函数名、方法名的函数方法
Jun 25 PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 PHP
PhpStorm本地断点调试的方法步骤
May 21 PHP
PHP使用SMTP邮件服务器发送邮件示例
Aug 28 PHP
php时间戳转换代码详解
Aug 04 PHP
TP5框架实现一次选择多张图片并预览的方法示例
Apr 04 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
php5.2时间相差8小时
2007/01/15 PHP
PHP APC缓存配置、使用详解
2014/03/06 PHP
PHP闭包函数详解
2016/02/13 PHP
php结合web uploader插件实现分片上传文件
2016/05/10 PHP
php常用字符串查找函数strstr()与strpos()实例分析
2019/06/21 PHP
Yii框架的布局文件实例分析
2019/09/04 PHP
用Laravel轻松处理千万级数据的方法实现
2020/12/25 PHP
javascript SocialHistory 检查访问者是否访问过某站点
2008/08/02 Javascript
jQuery 表单验证扩展(三)
2010/10/20 Javascript
ASP.NET jQuery 实例7 通过jQuery来获取DropDownList的Text/Value属性值
2012/02/03 Javascript
JavaScript window.document的属性、方法和事件小结
2012/10/24 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)
2015/08/04 Javascript
理解和运用JavaScript的闭包机制
2015/08/13 Javascript
vue 实现移动端键盘搜索事件监听
2019/11/06 Javascript
JS PHP字符串截取函数实现原理解析
2020/08/29 Javascript
Python中用Spark模块的使用教程
2015/04/13 Python
Python之py2exe打包工具详解
2017/06/14 Python
Django csrf 验证问题的实现
2018/10/09 Python
深入理解Django-Signals信号量
2019/02/19 Python
使用Python-OpenCV向图片添加噪声的实现(高斯噪声、椒盐噪声)
2019/05/28 Python
Python Django 简单分页的实现代码解析
2019/08/21 Python
Python Flask框架实现简单加法工具过程解析
2020/06/03 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
2020/08/07 Python
Python 实现劳拉游戏的实例代码(四连环、重力四子棋)
2021/03/03 Python
JD Sports德国官网:英国领先的运动鞋和运动服饰零售商
2018/02/26 全球购物
潘多拉意大利官方网上商城:网上选购PANDORA珠宝
2018/10/07 全球购物
KENZO官网:高田贤三在法国创立的品牌
2019/05/16 全球购物
Myprotein中国网站:欧洲畅销运动营养品牌
2021/02/11 全球购物
电大本科自我鉴定
2014/02/05 职场文书
励志演讲稿300字
2014/08/21 职场文书
法学专业大学生实习自我鉴定
2014/10/05 职场文书
2014年英语教学工作总结
2014/12/17 职场文书
社会主义核心价值观主题教育活动总结
2015/05/07 职场文书
Python echarts实现数据可视化实例详解
2022/03/03 Python
element tree树形组件回显数据问题解决
2022/08/14 Javascript