PHP的中使用非缓冲模式查询数据库的方法

发布时间 - 2026-01-10 22:52:32    点击率:

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

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

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

毕竟编程这么多年,我隐约记得PHP里提供有非一次全部加载数据的API,是像处理流媒体那样,随用随取随丢、数据并不会积累在内存的查询方法。经过简单的搜索,果然在官方网站上找到的正确的用法。缓冲查询和非缓冲查询(Buffered and Unbuffered queries)。PHP的查询缺省模式是缓冲模式。也就是说,查询数据结果会一次全部提取到内存里供PHP程序处理。这样给了PHP程序额外的功能,比如说,计算行数,将指针指向某一行等。更重要的是程序可以对数据集反复进行二次查询和过滤等操作。但这种缓冲查询模式的缺陷就是消耗内存。

另外一种PHP查询模式是非缓冲查询,数据库服务器会一条一条的返回数据,而不是一次全部返回,这样的结果就是PHP程序消耗较少的内存,但却增加了数据库服务器的压力,因为数据库会一直等待PHP来取数据,一直到数据全部取完。

非缓冲查询方法一: 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;
  }
}

注:引之 http://www.webhek.com/php-buffered-and-unbuffered-queries

手册资料 http://php.net/manual/zh/mysqlinfo.concepts.buffering.php


# PHP非缓冲模式  # PHP中数据库单例模式的实现代码分享  # php设计模式 DAO(数据访问对象模式)  # 浅析php设计模式之数据对象映射模式  # PHP基于单例模式实现的数据库操作基类  # PHP实现的数据对象映射模式详解  # PHP单例模式应用示例【多次连接数据库只实例化一次】  # PHP单例模式数据库连接类与页面静态化实现方法  # PHP数据对象映射模式实例分析  # PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析  # PHP数据源架构模式之表入口模式实例分析  # 的是  # 也就是说  # 加载  # 也不  # 我很  # 要把  # 给了  # 要用  # 但却  # 更重要  # 官方网  # 站上  # 流媒体  # 较少  # 错误信息  # 可想而知  # 才怪  # 而不是  # 增加了  # 行数 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel用户密码怎么加密_Laravel Hash门面使用教程  魔毅自助建站系统:模板定制与SEO优化一键生成指南  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  Laravel怎么上传文件_Laravel图片上传及存储配置  手机软键盘弹出时影响布局的解决方法  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  如何选择可靠的免备案建站服务器?  高防服务器:AI智能防御DDoS攻击与数据安全保障  Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  重庆市网站制作公司,重庆招聘网站哪个好?  如何用5美元大硬盘VPS安全高效搭建个人网站?  JavaScript如何实现类型判断_typeof和instanceof有什么区别  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  Laravel怎么实现搜索高亮功能_Laravel结合Scout与Algolia全文检索【实战】  如何快速查询域名建站关键信息?  图册素材网站设计制作软件,图册的导出方式有几种?  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Laravel怎么调用外部API_Laravel Http Client客户端使用  如何用好域名打造高点击率的自主建站?  Laravel如何发送系统通知?(Notification渠道示例)  Laravel如何实现模型的全局作用域?(Global Scope示例)  jQuery中的100个技巧汇总  Chrome浏览器标签页分组怎么用_谷歌浏览器整理标签页技巧【效率】  怎么用AI帮你为初创公司进行市场定位分析?  zabbix利用python脚本发送报警邮件的方法  Laravel如何升级到最新版本?(升级指南和步骤)  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  详解Android图表 MPAndroidChart折线图  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  Python面向对象测试方法_mock解析【教程】  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用  javascript中的try catch异常捕获机制用法分析  Laravel怎么为数据库表字段添加索引以优化查询  如何快速上传自定义模板至建站之星?  如何快速使用云服务器搭建个人网站?  如何实现javascript表单验证_正则表达式有哪些实用技巧  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  javascript基本数据类型及类型检测常用方法小结  bootstrap日历插件datetimepicker使用方法  如何在服务器上配置二级域名建站?  Laravel如何使用withoutEvents方法临时禁用模型事件  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  WEB开发之注册页面验证码倒计时代码的实现  Laravel如何使用Sanctum进行API认证?(SPA实战)  Laravel如何处理和验证JSON类型的数据库字段