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字符转义相关函数小结(php下的转义字符串)
Apr 12 PHP
php批量缩放图片的代码[ini参数控制]
Feb 11 PHP
探讨fckeditor在Php中的配置详解
Jun 08 PHP
ThinkPHP的截取字符串函数无法显示省略号的解决方法
Jun 25 PHP
php+jQuery.uploadify实现文件上传教程
Dec 26 PHP
PHP调试的强悍利器之PHPDBG
Feb 22 PHP
PHP MSSQL 分页实例
Apr 13 PHP
php判断是否为ajax请求的方法
Nov 29 PHP
如何通过View::first使用Laravel Blade的动态模板详解
Sep 21 PHP
php无限级分类实现评论及回复功能
Feb 18 PHP
PHP8.0新功能之Match表达式的使用
Jul 19 PHP
php优化查询foreach代码实例讲解
Mar 24 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游戏编程25个脚本代码
2011/02/08 PHP
Zend Framework中的简单工厂模式 图文
2012/07/10 PHP
清空上传控件input file的值
2010/07/03 Javascript
jquery实现可拖动DIV自定义保存到数据的实例
2013/11/20 Javascript
JS组件Bootstrap导航条使用方法详解
2016/04/29 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
浅析JavaScript动画模拟拖拽原理
2016/12/09 Javascript
bootstrap table使用入门基本用法
2017/05/24 Javascript
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
JS实现身份证输入框的输入效果
2017/08/21 Javascript
express+mockjs实现模拟后台数据发送功能
2018/01/07 Javascript
webpack打包js的方法
2018/03/12 Javascript
js实现简易计算器功能
2019/10/18 Javascript
Vue 2.0双向绑定原理的实现方法
2019/10/23 Javascript
Javascript操作select控件代码实例
2020/02/14 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
2020/07/19 Javascript
[56:18]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python中如何获取类属性的列表
2016/12/26 Python
Python冲顶大会 快来答题!
2018/01/17 Python
利用python循环创建多个文件的方法
2018/10/25 Python
django admin.py 外键,反向查询的实例
2019/07/26 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
python反扒机制的5种解决方法
2021/02/06 Python
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
中学生在校期间的自我评价分享
2013/11/13 职场文书
村捐赠仪式答谢词
2014/01/21 职场文书
音乐教学案例
2014/01/30 职场文书
《维生素c的故事》教学反思
2014/02/18 职场文书
会计专业导师推荐信
2014/03/08 职场文书
员工工作表现评语
2014/04/26 职场文书
店铺转让协议书(2014版)
2014/09/23 职场文书
向国旗敬礼活动总结范文2014
2014/09/27 职场文书
2015年幼儿园新年寄语
2014/12/08 职场文书
工作失职自我检讨书
2015/05/05 职场文书
清明节主题班会
2015/08/14 职场文书
Redis Stream类型的使用详解
2021/11/11 Redis