解决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 相关文章推荐
将OICQ数据转成MYSQL数据
Oct 09 PHP
PHP的error_reporting错误级别变量对照表
Jul 08 PHP
使用PHPMailer实现邮件发送代码分享
Oct 23 PHP
php数组保存文本与文本反编成数组实例
Nov 13 PHP
php使用指定编码导出mysql数据到csv文件的方法
Mar 31 PHP
初识PHP中的Swoole
Apr 05 PHP
详解Yii实现分页的两种方法
Jan 14 PHP
利用php的ob缓存机制实现页面静态化方法
Jul 09 PHP
PHP中危险的file_put_contents函数详解
Nov 04 PHP
PHP反射实际应用示例
Apr 03 PHP
php7下的filesize函数
Sep 30 PHP
PHP设计模式之 策略模式Strategy详解【对象行为型】
May 01 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
这部番真是良心,画质好到像风景区,剧情让人跟着小公会热血沸腾
2020/03/10 日漫
php各种编码集详解和以及在什么情况下进行使用
2011/09/11 PHP
php打印输出棋盘的实现方法
2014/12/23 PHP
smarty简单应用实例
2015/11/03 PHP
javascript 多浏览器 事件大全
2010/03/23 Javascript
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
2012/03/14 Javascript
页面装载js及性能分析方法介绍
2014/03/21 Javascript
js数组常见操作及数组与字符串相互转化实例详解
2015/11/10 Javascript
JavaScript基础语法之js表达式
2016/06/07 Javascript
简单实现JS倒计时效果
2016/12/23 Javascript
浅谈webpack性能榨汁机(打包速度优化)
2019/01/09 Javascript
深入Node TCP模块的理解
2019/03/13 Javascript
Nodejs中使用puppeteer控制浏览器中视频播放功能
2019/08/26 NodeJs
selenium+java中用js来完成日期的修改
2019/10/31 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
基于JS实现操作成功之后自动跳转页面
2020/09/25 Javascript
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
Python的time模块中的常用方法整理
2015/06/18 Python
Python多线程结合队列下载百度音乐的方法
2015/07/27 Python
Python编程中的异常处理教程
2015/08/21 Python
window下eclipse安装python插件教程
2017/04/24 Python
python 实现一个贴吧图片爬虫的示例
2017/10/12 Python
Python实现改变与矩形橡胶的线条的颜色代码示例
2018/01/05 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
Numpy之文件存取的示例代码
2018/08/03 Python
python实现整数的二进制循环移位
2019/03/08 Python
Python多进程编程multiprocessing代码实例
2020/03/12 Python
Python实现Word表格转成Excel表格的示例代码
2020/04/16 Python
Python读取excel文件中带公式的值的实现
2020/04/17 Python
Django实现前台上传并显示图片功能
2020/05/29 Python
HTML5不支持frameset的两种解决方法
2016/11/14 HTML / CSS
高分子材料与工程专业推荐信
2013/12/01 职场文书
乡镇精神文明建设汇报材料
2014/08/15 职场文书
教代会闭幕词
2015/01/28 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书
优秀党员主要事迹材料
2015/11/04 职场文书