解决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 25 PHP
php全局变量和类配合使用深刻理解
Jun 05 PHP
PHP中将ip地址转成十进制数的两种实用方法
Aug 15 PHP
php缩小png图片不损失透明色的解决方法
Dec 25 PHP
php中常见的sql攻击正则表达式汇总
Nov 06 PHP
php使用post数组的键值创建同名变量并赋值的方法
Apr 03 PHP
PHP 数组基本操作方法详解
Jun 17 PHP
php 指定范围内多个随机数代码实例
Jul 18 PHP
Thinkphp框架开发移动端接口(1)
Aug 18 PHP
PHP简单实现模拟登陆功能示例
Sep 15 PHP
常见的5个PHP编码小陋习以及优化实例讲解
Feb 27 PHP
利用ajax+php实现商品价格计算
Mar 31 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 中的一些经验积累
2006/10/09 PHP
php Static关键字实用方法
2010/06/04 PHP
redis 队列操作的例子(php)
2012/04/12 PHP
探讨PHP删除文件夹的三种方法
2013/06/09 PHP
zeroclipboard复制到剪切板的flash
2010/08/04 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
基于HTML5上使用iScroll实现下拉刷新,上拉加载更多
2016/05/21 Javascript
浅谈bootstrap源码分析之scrollspy(滚动侦听)
2016/06/06 Javascript
jQuery实现表格文本框淡入更改值后淡出效果
2016/09/27 Javascript
深入理解bootstrap框架之第二章整体架构
2016/10/09 Javascript
JavaScript日期选择功能示例
2017/01/16 Javascript
js实现显示手机号码效果
2017/03/09 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
vue构建动态表单的方法示例
2018/09/22 Javascript
原生JS实现烟花效果
2020/03/10 Javascript
Vue数据双向绑定原理实例解析
2020/05/15 Javascript
支付宝小程序实现省市区三级联动
2020/06/21 Javascript
js实现全选和全不选功能
2020/07/28 Javascript
[52:03]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第三场 1月31日
2021/03/11 DOTA
Python数据报表之Excel操作模块用法分析
2019/03/11 Python
GitHub 热门:Python 算法大全,Star 超过 2 万
2019/04/29 Python
Numpy一维线性插值函数的用法
2020/04/22 Python
Python3.7安装pyaudio教程解析
2020/07/24 Python
ProBikeKit美国官网:自行车套件,跑步和铁人三项套件
2016/10/13 全球购物
购房个人委托书范本
2014/10/11 职场文书
2015年设计师个人工作总结
2015/04/25 职场文书
借条如何写
2015/05/26 职场文书
幼儿园2016年感恩节活动总结
2016/04/01 职场文书
创业计划书之小型广告公司
2019/10/22 职场文书
python Polars库的使用简介
2021/04/21 Python
pandas中DataFrame重置索引的几种方法
2021/05/24 Python
尝试使用Python爬取城市租房信息
2022/04/12 Python
python中 .npy文件的读写操作实例
2022/04/14 Python