解决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中文分词 自动获取关键词介绍
Nov 13 PHP
浅析php中三个等号(===)和两个等号(==)的区别
Aug 06 PHP
ThinkPHP利用PHPMailer实现邮件发送实现代码
Sep 26 PHP
php实现图形显示Ip地址的代码及注释
Jan 20 PHP
php实现多维数组中每个单元值(数字)翻倍的方法
Feb 16 PHP
Symfony控制层深入详解
Mar 17 PHP
功能强大的php分页函数
Jul 20 PHP
PHPMailer发送邮件
Dec 28 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
May 09 PHP
Laravel框架生命周期与原理分析
Jun 12 PHP
PHP实现的简单留言板功能示例【基于thinkPHP框架】
Dec 07 PHP
php中加密解密DES类的简单使用方法示例
Mar 26 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中用数组的方法设置cookies
2011/04/21 PHP
Linux下创建nginx脚本-start、stop、reload…
2014/08/03 PHP
文本加密解密
2006/06/23 Javascript
JavaScript原型继承之基础机制分析
2011/08/26 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
jQuery源码解读之hasClass()方法分析
2015/02/20 Javascript
拥有一个属于自己的javascript表单验证插件
2016/03/24 Javascript
一览画面点击复选框后获取多个id值的方法
2016/05/30 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
2016/11/18 Javascript
AngularJS实现DOM元素的显示与隐藏功能
2016/11/22 Javascript
JavaScript计时器用法分析【setTimeout和clearTimeout】
2017/01/18 Javascript
Python使用SocketServer模块编写基本服务器程序的教程
2016/07/12 Python
Django基础之Model操作步骤(介绍)
2017/05/27 Python
30秒轻松实现TensorFlow物体检测
2018/03/14 Python
selenium+python自动化测试之页面元素定位
2019/01/23 Python
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
Django ORM 聚合查询和分组查询实现详解
2019/08/09 Python
pytorch使用指定GPU训练的实例
2019/08/19 Python
使用HTML5原生对话框元素并轻松创建模态框组件
2019/03/06 HTML / CSS
HTML5 拖放功能实现代码
2016/07/14 HTML / CSS
Free People中国官网:波西米亚风格女装服饰
2016/08/30 全球购物
Banana Republic英国官网:香蕉共和国,GAP集团旗下偏贵族风
2018/04/24 全球购物
htmlentities() 和 htmlspecialchars()有什么区别
2015/07/01 面试题
写出二分查找算法的两种实现
2013/05/13 面试题
什么是设计模式
2012/06/17 面试题
会计学财务管理专业个人的自我评价
2013/10/19 职场文书
秋季运动会稿件
2014/01/30 职场文书
支行行长竞聘演讲稿
2014/05/15 职场文书
2014年办公室文员工作总结
2014/11/12 职场文书
六年级学生评语大全
2014/12/26 职场文书
师德师风心得体会(2016精选篇)
2016/01/12 职场文书
导游词之天津盘山
2019/11/01 职场文书
小学四年级作文之人物作文
2019/11/06 职场文书
Nginx反向代理至go-fastdfs案例讲解
2021/08/02 Servers
Mysql中有关Datetime和Timestamp的使用总结
2021/12/06 MySQL