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


Posted in PHP onFebruary 05, 2017

最近在开发一个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的错误信息
Oct 09 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
Nov 30 PHP
PHP下判断网址是否有效的代码
Oct 08 PHP
php中3des加密代码(完全与.net中的兼容)
Aug 02 PHP
PHP 验证码不显示只有一个小红叉的解决方法
Sep 30 PHP
php实现复制移动文件的方法
Jul 29 PHP
php批量删除超链接的实现方法
Oct 19 PHP
PHP获取网页所有连接的方法(附demo源码下载)
Mar 30 PHP
php之header的不同用法总结(实例讲解)
Nov 28 PHP
yii2中关于加密解密的那些事儿
Jun 12 PHP
laravel-admin select框默认选中的方法
Oct 03 PHP
Laravel Reponse响应客户端示例详解
Sep 03 PHP
php+redis在实际项目中HTTP 500: Internal Server Error故障排除
Feb 05 #PHP
php实现给二维数组中所有一维数组添加值的方法
Feb 04 #PHP
PHP进制转换实例分析(2,8,16,36,64进制至10进制相互转换)
Feb 04 #PHP
php加密之discuz内容经典加密方式实例详解
Feb 04 #PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
Feb 04 #PHP
PHP正则表达式匹配替换与分割功能实例浅析
Feb 04 #PHP
/etc/php-fpm.d/www.conf 配置注意事项
Feb 04 #PHP
You might like
扩展你的 PHP 之入门篇
2006/12/04 PHP
PHP 之 写时复制介绍(Copy On Write)
2014/05/13 PHP
php使用explode()函数将字符串拆分成数组的方法
2015/02/17 PHP
Yii框架getter与setter方法功能与用法分析
2019/10/22 PHP
php命令行模式代码实例详解
2021/02/26 PHP
Docker 安装 PHP并与Nginx的部署实例讲解
2021/02/27 PHP
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
2007/02/23 Javascript
.net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
2013/03/11 Javascript
一个JavaScript递归实现反转数组字符串的实例
2014/10/14 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
超链接怎么正确调用javascript函数
2016/05/23 Javascript
bootstrap下拉列表与输入框组结合的样式调整
2016/10/08 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
详解微信小程序 template添加绑定事件
2017/06/23 Javascript
红黑树的插入详解及Javascript实现方法示例
2018/03/26 Javascript
js计算最大公约数和最小公倍数代码实例
2019/09/11 Javascript
Vue实现验证码功能
2019/12/03 Javascript
纯js+css实现仿移动端淘宝网站的弹出详情框功能
2019/12/29 Javascript
解决node终端下运行js文件不支持ES6语法
2020/04/04 Javascript
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
在Docker上开始部署Python应用的教程
2015/04/17 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
python经典趣味24点游戏程序设计
2019/07/26 Python
Django--权限Permissions的例子
2019/08/28 Python
python之列表推导式的用法
2019/11/29 Python
Selenium元素定位的30种方式(史上最全)
2020/05/11 Python
使用css3 属性如何丰富图片样式(圆角 阴影 渐变)
2012/11/22 HTML / CSS
西班牙手机之家:Phone House
2018/10/18 全球购物
城管综合整治方案
2014/05/01 职场文书
服务标语口号
2014/07/01 职场文书
影视后期实训报告
2014/11/05 职场文书
杭州黄龙洞导游词
2015/02/10 职场文书
中小企业员工手册范本
2015/05/14 职场文书
sql server偶发出现死锁的解决方法
2022/04/10 SQL Server
git中cherry-pick命令的使用教程
2022/06/25 Servers