解决PHP里大量数据循环时内存耗尽的方法

 更新时间:2015年10月10日 11:25:39   投稿:mrr  
错误信息提示最大内存已经耗尽,该如何解决呢?下面小编给大家解决PHP里大量数据循环时内存耗尽的问题,需要的朋友可以参考下

最近在开发一个PHP程序的时候遇到如下一问题:

PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted

错误信息显示允许的最大内存已经耗尽。遇到这样的错误起初让我很诧异,但转眼一想,也不奇怪,因为我正在开发的这个程序是要用一个foreach循环语句在一个有4万条记录的表里全表搜索具有特定特征的数据,也就是说,一次要把4万条数据取出,然后逐条检查每天数据。可想而知,4万条数据全部加载到内存中,内存不爆才怪。

 

毕竟编程这么多年,我隐约记得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里大量数据循环时内存耗尽的方法,希望对大家有所帮助。

相关文章

  • laravel使用数据库测试注意事项

    laravel使用数据库测试注意事项

    这篇文章主要介绍了laravel使用数据库测试注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • php脚本运行时的超时机制详解

    php脚本运行时的超时机制详解

    在我们平常的开发中,也许曾经都遇到过PHP脚本运行超时的情况,当遇到这种情况我们经常会通过使用 set_time_limit(非安全模式),或修改配置文件并重启服务器,或者修改程序减少程序的执行时间,使其在允许的范围之内,以解决此问题。
    2016-02-02
  • PHP读取mssql json数据中文乱码的解决办法

    PHP读取mssql json数据中文乱码的解决办法

    PHP及网页使用UTF-8编码,数据库是sql server2008,使用默认编码,当读取数据库数据时,使用php自带的json_encode()返回到前端,结果中文不显示。下面脚本之家小编给大家介绍PHP读取mssql json数据中文乱码的解决办法,需要的朋友一起学习
    2016-04-04
  • PHP实现的多彩标签效果代码分享

    PHP实现的多彩标签效果代码分享

    这篇文章主要介绍了PHP实现的多彩标签效果代码分享,经常可以看到一些博客中的标签(TAGS)页面是彩色的效果展现,本文就给出了实现这个功能的PHP代码,需要的朋友可以参考下
    2014-08-08
  • Yii2.0建立公共方法简单示例

    Yii2.0建立公共方法简单示例

    这篇文章主要介绍了Yii2.0建立公共方法,结合实例形式分析了Yii2.0建立公共方法的基本原理、步骤与相关操作注意事项,需要的朋友可以参考下
    2019-01-01
  • PHP数据类型之整数类型、浮点数的介绍

    PHP数据类型之整数类型、浮点数的介绍

    本篇文章介绍了,PHP数据类型之整数类型、浮点数的介绍。需要的朋友参考下
    2013-04-04
  • PHP中的日期加减方法示例

    PHP中的日期加减方法示例

    这篇文章主要介绍了PHP中的日期加减方法示例,主要是对date()函数和strtotime()函数使用,需要的朋友可以参考下
    2014-08-08
  • php判断手机浏览还是web浏览,并执行相应的动作简单实例

    php判断手机浏览还是web浏览,并执行相应的动作简单实例

    下面小编就为大家带来一篇php判断手机浏览还是web浏览,并执行相应的动作简单实例。小编觉得挺不错的,现在就分享给大家,也给的大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • Zend Framework实现多文件上传功能实例

    Zend Framework实现多文件上传功能实例

    这篇文章主要介绍了Zend Framework实现多文件上传功能的方法,较为详细的分析说明了Zend Framework实现多文件上传的具体步骤与相关实现技巧,需要的朋友可以参考下
    2016-03-03
  • laravel执行php artisan migrate报错的解决方法

    laravel执行php artisan migrate报错的解决方法

    今天小编就为大家分享一篇laravel执行php artisan migrate报错的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10

最新评论