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 相关文章推荐
3
Oct 09 PHP
十天学会php(3)
Oct 09 PHP
PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
Jul 23 PHP
解析thinkphp中的导入文件标签
Jun 20 PHP
php cookie使用方法学习笔记分享
Nov 07 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
Apr 28 PHP
php按百分比生成缩略图的代码分享
May 10 PHP
PHP 500报错的快速解决方法
Dec 14 PHP
PHP基于新浪IP库获取IP详细地址的方法
May 04 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
Jul 08 PHP
laravel 实现用户登录注销并限制功能
Oct 24 PHP
PHP设计模式(六)桥连模式Bridge实例详解【结构型】
May 02 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/10/09 PHP
apache2.2.4+mysql5.0.77+php5.2.8安装精简
2009/04/29 PHP
PHP 上传文件大小限制
2009/07/05 PHP
php实现短信发送代码
2015/07/05 PHP
实例说明js脚本语言和php脚本语言的区别
2019/04/04 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
JS对文本框值的判断示例
2014/03/10 Javascript
jquery缓动swing liner控制动画过程不同时刻的速度
2014/05/29 Javascript
3个可以改善用户体验的AngularJS指令介绍
2015/06/18 Javascript
基于RequireJS和JQuery的模块化编程——常见问题全面解析
2016/04/14 Javascript
懒加载实现的分页&amp;&amp;网站footer自适应
2016/12/21 Javascript
jquery横向纵向鼠标滚轮全屏切换
2017/02/27 Javascript
jQuery实现验证码功能
2017/03/17 Javascript
vue 设置proxyTable参数进行代理跨域
2018/04/09 Javascript
js实现简单模态框实例
2018/11/16 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
JS如何调用WebAssembly编译出来的.wasm文件
2020/11/05 Javascript
[01:16:01]VGJ.S vs Mski Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[39:18]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第二场 12.17
2020/12/19 DOTA
python基于windows平台锁定键盘输入的方法
2015/03/05 Python
在Python中使用Mako模版库的简单教程
2015/04/08 Python
python Django模板的使用方法
2016/01/14 Python
Swift中的协议(protocol)学习教程
2016/07/08 Python
Python3实现从排序数组中删除重复项算法分析
2019/04/03 Python
对python中assert、isinstance的用法详解
2019/11/27 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
医学专业五年以上个人求职信
2013/12/03 职场文书
高中运动会广播稿
2015/08/19 职场文书
演讲稿之感恩老师(三篇范文)
2019/09/06 职场文书
Python list去重且保持原顺序不变的方法
2021/04/03 Python
python中Tkinter 窗口之输入框和文本框的实现
2021/04/12 Python
mysql在项目中怎么选事务隔离级别
2021/05/25 MySQL
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
JavaScript实现两个数组的交集
2022/03/25 Javascript