如何解决PHP里大量数据循环时内存耗尽的问题

最近在开发一个PHP程序时遇到了下面的错误:


  1. 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


  1. <?php 
  2. $mysqli  = new mysqli("localhost", "my_user", "my_password", "world"); 
  3. $uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); 
  4.  
  5. if ($uresult) { 
  6.    while ($row = $uresult->fetch_assoc()) { 
  7.        echo $row['Name'] . PHP_EOL; 
  8.    } 
  9. $uresult->close(); 
  10. ?> 

非缓冲查询方法二: pdo_mysql


  1. <?php 
  2. $pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); 
  3. $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); 
  4.  
  5. $uresult = $pdo->query("SELECT Name FROM City"); 
  6. if ($uresult) { 
  7.    while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { 
  8.        echo $row['Name'] . PHP_EOL; 
  9.    } 
  10. ?> 

非缓冲查询方法三: mysql


  1. <?php 
  2. $conn = mysql_connect("localhost", "my_user", "my_pass"); 
  3. $db   = mysql_select_db("world"); 
  4.  
  5. $uresult = mysql_unbuffered_query("SELECT Name FROM City"); 
  6. if ($uresult) { 
  7.    while ($row = mysql_fetch_assoc($uresult)) { 
  8.        echo $row['Name'] . PHP_EOL; 
  9.    } 
  10. ?> 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索php
, 内存
, 数据
, 查询
, 缓冲
, 模式
, 数据库查询问题
, 查询循环问题
, 大数据查询优化问题
, 循环查询
, 查询问题数据
, 服务器流媒体缓冲
, MQ耗尽内存
amqrmppa 耗尽内存
天刀内存耗尽怎么解决、解决天刀内存耗尽、linux inode 耗尽解决、结果集已耗尽怎么解决、天谕显存耗尽怎么解决,以便于您获取更多的相关知识。

时间: 2024-09-14 21:58:41

如何解决PHP里大量数据循环时内存耗尽的问题的相关文章

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

最近在开发一个PHP程序的时候遇到如下一问题: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 错误信息显示允许的最大内存已经耗尽.遇到这样的错误起初让我很诧异,但转眼一想,也不奇怪,因为我正在开发的这个程序是要用一个foreach循环语句在一个有4万条记录的表里全表搜索具有特定特征的数据,也就是说,一次要把4万条数据取出,然后逐条检查每天数据.可想而知,4万条数据全部加载到内存中,内存不爆才怪.   毕竟编

io流-listFiles 大数据量时内存溢出

问题描述 listFiles 大数据量时内存溢出 描述: 获取一个文件集合,通过文件获取文件名集合,再根据文件内容筛选文件,存储在Map里 问题: 文件服务器A文件夹下,存在近7万个文件,以XML格式存储,调用listFiles,再做put操作时, 内存就会溢出,调整过eclipse的堆与非堆内存,加大了1024M,也同样抛出内存溢出异常, 恳请大家指点迷津,给个好的解决方案,或者案例参考,谢谢了 这个方法需要将内容存储在Map对象内然后返回这个Map对象,给其他成员调用,这个内存溢出,因该是在

解决Linux下php-fpm进程过多导致内存耗尽问题

最近,发现个人博客的Linux服务器,数据库服务经常挂掉,导致需要重启,才能正常访问,极其恶心,于是决心开始解决问题,解放我的时间和精力(我可不想经常出问题,然后人工重启,费力费时). 分析问题 发现问题以后,首先使用 free -m 指令查看当前服务器执行状况: 可以看到我的服务器内存是2G的,但是目前可用内存只剩下70M,内存使用率高达92%,很有可能是内存使用率过高导致数据库服务挂断. 继续看详细情况,使用 top 指令: 然后再看指令输出结果中详细列出的进程情况,重点关注第10列内存使用

求助:C#里向临时建立的datatable里填充数据为什么占内存那么大?有方法解决吗?

问题描述 我在C#程序里想实现将一个50M左右的数据拆分,放入临时建立的datatable里,然后对datatable进行操作.但是,当我把50M的数据全部按自己定义的字符串字段添加到datatable里以后,发现我的C#程序占内存达到了恐怖的750M--如果只把这50M数据以字符串的形式读入到C#中占的内存不到200M,不知道为什么差别会这么大?哪位高手帮忙解释一下!跪求解决方法! 解决方案 解决方案二:SqlDataReader代替解决方案三:高深呢.解决方案四:datatable每一次用完

moloch导入离线数据包时含有大量DNS协议会话时一直占用大量内存直至死机

问题描述 moloch导入离线数据包时含有大量DNS协议会话时一直占用大量内存直至死机 有谁用过moloch分析数据包啊?每次解析很多DNS协议时内存都一直到内存占满i直接卡死,有谁知道怎么回事?解析其他数据包时内存占用也会一直涨但是很慢很慢 解决方案 http://www.freebuf.com/tools/9359.html

循环往Map里装数据,同一个KEY的数据撞到一个list中,怎么实现?急急

问题描述 循环往Map里装数据,同一个KEY的数据撞到一个list中,怎么实现?急急 Map<String, List<UserDto>> map = new HashMap<String, List<UserDto>>(); String key = ""; for (int i = 0 ;i < userErrorList.size(); i++) { key = userErrorList.get(i).getUserId()

adb-VS2010用C#将数据库里的数据读出并显示到界面时 出错,求各位老师帮忙

问题描述 VS2010用C#将数据库里的数据读出并显示到界面时 出错,求各位老师帮忙 private void listView_shipinfo_MouseClick(object sender, MouseEventArgs e) { string des_string = lvselecteditem(); SqlConnection Conn = new SqlConnection(); Conn.ConnectionString = "Server=Localhost;" +

如何解决mysql查询百万数据时出现大量sleep的进程

问题描述 如何解决mysql查询百万数据时出现大量sleep的进程 如何解决mysql查询百万数据时出现大量sleep的进程: 当使用jdbc 查询数据量为100多万的数据时,mysql会出现大量sleep的进程,然后程序便会卡死在那儿 解决方案 描述的有点泛泛,如果能把使用场景.涉及库表定义发一下会更容易分析. 大量sleep进程可能并不是问题,因为如果使用到连接池的话,一开始就是初始化一些连接,这些连接没有使用的话,在mysql看可能就是sleep的. 从你描述,感觉"查询数据量为100多万

在快速排序里,进行数据交换时,遇到的特殊问题

问题描述 在快速排序里,进行数据交换时,遇到的特殊问题 #include<stdio.h> #include<stdlib.h> #include<time.h> //////////////快速排序/////////////////// void quicksort(int* src,int start,int end) { int l=start,r=end; int key=0; int mid=0; if(start>=end) return; /////