解决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 相关文章推荐
简单示例AJAX结合PHP代码实现登录效果代码
Jul 25 PHP
php递归实现无限分类生成下拉列表的函数
Aug 08 PHP
PHP简单的MVC框架实现方法
Dec 01 PHP
配置Nginx+PHP的正确思路与过程
May 10 PHP
PHP实现简单ajax Loading加载功能示例
Dec 28 PHP
yii2 resetful 授权验证详解
May 18 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
May 25 PHP
Laravel框架路由设置与使用示例
Jun 12 PHP
PDO::quote讲解
Jan 29 PHP
PHP PDOStatement::bindParam讲解
Jan 30 PHP
thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例
Aug 13 PHP
PHP使用openssl扩展实现加解密方法示例
Feb 20 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中Stream(流)
2015/06/08 PHP
Linux下从零开始安装配置Nginx服务器+PHP开发环境
2015/12/21 PHP
PHP AjaxForm提交图片上传并显示图片源码
2016/11/29 PHP
微信小程序发送订阅消息的方法(php 为例)
2019/10/30 PHP
Mootools 1.2教程 定时器和哈希简介
2009/09/15 Javascript
js trim函数 去空格函数与正则集锦
2009/11/20 Javascript
javascript两段代码,两个小技巧
2010/02/04 Javascript
input标签内容改变的触发事件介绍
2014/06/18 Javascript
Jquery ajax加载等待执行结束再继续执行下面代码操作
2015/11/24 Javascript
JS+Canvas绘制时钟效果
2020/08/20 Javascript
微信小程序实现自定义加载图标功能
2018/07/19 Javascript
在create-react-app中使用css modules的示例代码
2018/07/31 Javascript
微信小程序云开发实现云数据库读写权限
2019/05/17 Javascript
JS实现随机抽选获奖者
2019/11/07 Javascript
微信小程序input抖动问题的修复方法
2021/03/03 Javascript
[01:24:09]Ti4 冒泡赛第二轮DK vs C9 1
2014/07/14 DOTA
[00:32]2018DOTA2亚洲邀请赛VG出场
2018/04/03 DOTA
Python + selenium + requests实现12306全自动抢票及验证码破解加自动点击功能
2018/11/23 Python
Python编程在flask中模拟进行Restful的CRUD操作
2018/12/28 Python
python实现得到当前登录用户信息的方法
2019/06/21 Python
django 实现将本地图片存入数据库,并能显示在web上的示例
2019/08/07 Python
Django rstful登陆认证并检查session是否过期代码实例
2019/08/13 Python
Django实现auth模块下的登录注册与注销功能
2019/10/10 Python
python KNN算法实现鸢尾花数据集分类
2019/10/24 Python
pandas统计重复值次数的方法实现
2021/02/20 Python
北美最大的零售退货翻新商:VIP Outlet
2019/11/21 全球购物
九州传奇上机题
2014/07/10 面试题
企业演讲稿范文大全
2014/05/20 职场文书
护士优质服务演讲稿
2014/08/26 职场文书
防灾减灾标语
2014/10/07 职场文书
幼儿园教师求职信
2015/03/20 职场文书
2015年营业员工作总结
2015/04/23 职场文书
2015秋季运动会通讯稿
2015/07/18 职场文书
幼儿园中班教学反思
2016/03/03 职场文书
js基础语法与maven项目配置教程案例
2021/07/15 Javascript
分享几种python 变量合并方法
2022/03/20 Python