热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

 $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

 $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

 $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程序如何成功连接MySQL数据库的方法,包括常见的连接失败原因及解决方案。 ... [详细]
  • 本文详细记录了《PHP与MySQL Web开发》第一章的学习心得,特别关注了PHP的基本构成元素、标记风格、编程注意事项及表单处理技巧等内容。 ... [详细]
  • 深入理解FastDFS
    FastDFS是一款高效、简洁的分布式文件系统,广泛应用于互联网应用中,用于处理大量用户上传的文件,如图片、视频等。本文探讨了FastDFS的设计理念及其如何通过独特的架构设计提高性能和可靠性。 ... [详细]
  • 本文探讨了如何在JavaScript中调用PHP函数及实现两者之间的有效交互,包括通过AJAX请求、动态生成JavaScript代码等方法。 ... [详细]
  • MySQL中如何为字段添加注释
    本文详细介绍了在MySQL数据库中为字段添加注释的两种方法,并提供了具体的SQL语句示例,帮助开发者更好地管理和理解数据库结构。 ... [详细]
  • HTML中用于创建表单的标签是什么
    本文将详细介绍HTML中用于创建表单的标签及其基本用法,包括表单的主要特性和常用的属性设置。如果您正在学习HTML或需要了解如何在网页中添加表单,这将是一个很好的起点。 ... [详细]
  • SQL注入实验:SqliLabs第38至45关解析
    本文深入探讨了SqliLabs项目中的第38至45关,重点讲解了堆叠注入(Stacked Queries)的应用技巧及防御策略。通过实际案例分析,帮助读者理解如何利用和防范此类SQL注入攻击。 ... [详细]
  • KKCMS代码审计初探
    本文主要介绍了KKCMS的安装过程及其基本功能,重点分析了该系统中存在的验证码重用、SQL注入及XSS等安全问题。适合初学者作为入门指南。 ... [详细]
  • 致信息安全爱好者的成长指南
    本文旨在为信息安全爱好者提供一份详尽的成长指南,涵盖从学习心态调整到具体技能提升的各个方面。 ... [详细]
  • 本文详细探讨了在Windows Server 2003环境下遇到MySQL连接失败(错误代码10061)的解决方案,包括通过卸载特定的Windows更新和调整系统注册表设置的方法。 ... [详细]
  • 尝试从 MySQL 转向 SQL Server 2008 时遇到了安装错误,提示“系统配置未能初始化”,错误代码为 0x84B10001。怀疑可能是由于之前的 MySQL 安装残留导致的注册表问题。寻求专家建议。 ... [详细]
  • 解决getallheaders函数导致的500错误及8种服务器性能优化策略
    本文探讨了解决getallheaders函数引起的服务器500错误的方法,并介绍八种有效的服务器性能优化技术,包括内存数据库的应用、Spark RDD的使用、缓存策略的实施、SSD的引入、数据库优化、IO模型的选择、多核处理策略以及分布式部署方案。 ... [详细]
  • Kafka组件详解及工作原理
    本文介绍了Apache Kafka的核心组件及其工作方式,包括生产者(Producer)、消费者(Consumer)、主题(Topic)、代理(Broker)、分区(Partition)、消费者组(Consumer Group)和偏移量(Offset),并探讨了这些组件之间的交互机制。 ... [详细]
  • PHP中的Content-Type含义及其功能解析
    在PHP中,Content-Type头部信息用于定义资源的媒体类型(MIME类型),这对于确保客户端正确解析服务器响应至关重要。 ... [详细]
  • 本文详细介绍了MySQL中关于员工数据库的基础知识、操作技巧以及常见问题的解决方案,适合初学者和有一定基础的用户阅读。 ... [详细]
author-avatar
swaimprichett_556
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有