解决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&amp;mysql(四)
Oct 09 PHP
PHP中对用户身份认证实现两种方法
Jun 04 PHP
php中用加号与用array_merge合并数组的区别深入分析
Jun 03 PHP
深入php多态的实现详解
Jun 09 PHP
php实现文件下载简单示例(代码实现文件下载)
Mar 10 PHP
ThinkPHP无限级分类原理实现留言与回复功能实例
Oct 31 PHP
深入讲解PHP的Yii框架中的属性(Property)
Mar 18 PHP
PHP中单例模式与工厂模式详解
Feb 17 PHP
PHP更安全的密码加密机制Bcrypt详解
Jun 18 PHP
PHP中PDO事务处理操作示例
May 02 PHP
php使用curl模拟浏览器表单上传文件或者图片的方法
Nov 10 PHP
thinkphp5.1框架容器与依赖注入实例分析
Jul 23 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 攻击方法之谈php+mysql注射语句构造
2009/10/30 PHP
实例介绍PHP的Reflection反射机制
2014/08/05 PHP
Yii2中如何使用modal弹窗(基本使用)
2016/05/30 PHP
php+mysql开发的最简单在线题库(在线做题系统)完整案例
2019/03/30 PHP
JavaScript获取GridView中用户点击控件的行号,列号
2009/04/14 Javascript
js 实现无缝滚动 兼容IE和FF
2009/07/15 Javascript
js特效,页面下雪的小例子
2013/06/17 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
2015/08/11 Javascript
jQuery实现仿百度首页滑动伸缩展开的添加服务效果代码
2015/09/09 Javascript
Bootstrap基本插件学习笔记之Tooltip提示工具(18)
2016/12/08 Javascript
jQuery插件DataTable使用方法详解(.Net平台)
2016/12/22 Javascript
Bootstrap的modal拖动效果
2016/12/25 Javascript
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
2017/11/20 Javascript
JavaScript设计模式之构造器模式(生成器模式)定义与用法实例分析
2018/07/26 Javascript
小程序rich-text组件如何改变内部img图片样式的方法
2019/05/22 Javascript
vue开发拖拽进度条滑动组件
2019/09/21 Javascript
Python实现购物车程序
2018/04/16 Python
Pandas 按索引合并数据集的方法
2018/11/15 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
Python字典的核心底层原理讲解
2019/01/24 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
Flask框架学习笔记之表单基础介绍与表单提交方式
2019/08/12 Python
python 爬取学信网登录页面的例子
2019/08/13 Python
PyQt5 界面显示无响应的实现
2020/03/26 Python
Python中logging日志记录到文件及自动分割的操作代码
2020/08/05 Python
python合并多个excel文件的示例
2020/09/23 Python
python dir函数快速掌握用法技巧
2020/12/09 Python
Css3新特性应用之形状总结
2016/12/08 HTML / CSS
Otticanet意大利:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/03/10 全球购物
纯净、自信、100%的羊绒服装:360Cashmere
2021/02/20 全球购物
毕业典礼演讲稿
2014/05/13 职场文书
工商管理本科生求职信
2014/07/13 职场文书
医院我们的节日活动实施方案
2014/08/22 职场文书
2015秋季开学典礼新闻稿
2015/07/17 职场文书
上手简单,功能强大的Python爬虫框架——feapder
2021/04/27 Python
Mybatis-plus在项目中的简单应用
2021/07/01 Java/Android