解决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 相关文章推荐
smarty实例教程
Nov 19 PHP
一个PHP分页类的代码
May 18 PHP
ThinkPHP自动验证失败的解决方法
Jun 09 PHP
ThinkPHP3.1.3版本新特性概述
Jun 19 PHP
ThinkPHP3.1之D方法实例详解
Jun 20 PHP
smarty模板引擎中内建函数if、elseif和else的使用方法
Jan 22 PHP
ThinkPHP中数据操作案例分析
Sep 27 PHP
总结PHP删除字符串最后一个字符的三种方法
Aug 30 PHP
Thinkphp框架 表单自动验证登录注册 ajax自动验证登录注册
Dec 27 PHP
thinkPHP简单调用函数与类库的方法
Mar 15 PHP
PHP+MariaDB数据库操作基本技巧备忘总结
May 21 PHP
php生成word并下载代码实例
Mar 15 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 图像函数大举例(非原创)
2009/06/20 PHP
HTML中嵌入PHP的简单方法
2016/02/16 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
Yii2.0框架模型添加/修改/删除数据操作示例
2019/07/18 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
爆炸式的JS圆形浮动菜单特效代码
2010/03/03 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
Bootstrap栅格系统学习笔记
2016/11/25 Javascript
javascript 显示全局变量与隐式全局变量的区别
2017/02/09 Javascript
js按条件生成随机json:randomjson实现方法
2017/04/07 Javascript
使用AngularJS对表单提交内容进行验证的操作方法
2017/07/12 Javascript
Vue.extend构造器的详解
2017/07/17 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
2019/05/16 Javascript
微信小程序开发打开另一个小程序的实现方法
2020/05/17 Javascript
vue实现从外部修改组件内部的变量的值
2020/07/30 Javascript
vue打开子组件弹窗都刷新功能的实现
2020/09/21 Javascript
JavaScript实现移动端拖动元素
2020/11/24 Javascript
Python判断字符串与大小写转换
2015/06/08 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
Python内置加密模块用法解析
2019/11/25 Python
Pycharm自带Git实现版本管理的方法步骤
2020/09/18 Python
python 使用xlsxwriter循环向excel中插入数据和图片的操作
2021/01/01 Python
移动Web—CSS为Retina屏幕替换更高质量的图片
2012/12/24 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
庆七一活动方案
2014/01/25 职场文书
标准的毕业生自荐信
2014/04/20 职场文书
团支部建设方案
2014/05/02 职场文书
答谢会策划方案
2014/05/12 职场文书
纪检监察建议书
2014/05/19 职场文书
中学推普周活动总结
2015/05/07 职场文书
文明和谐家庭事迹材料(2016精选版)
2016/02/29 职场文书
七年级作文之雪景
2019/11/18 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS
十大最强妖精系宝可梦,哲尔尼亚斯实力最强,第五被称为大力士
2022/03/18 日漫
简单聊聊Golang中defer预计算参数
2022/03/25 Golang
教你nginx跳转配置的四种方式
2022/07/07 Servers