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 5.3 下载时 VC9、VC6、Thread Safe、Non Thread Safe的区别分析
Mar 28 PHP
php学习笔记之 函数声明
Jun 09 PHP
php Calender(日历)代码分享
Jan 03 PHP
PHP函数实现分页含文本分页和数字分页
Oct 23 PHP
php静态文件返回304技巧分享
Jan 06 PHP
PHP的Yii框架中移除组件所绑定的行为的方法
Mar 18 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
Mar 04 PHP
Laravel学习教程之路由模块
Aug 18 PHP
Laravel中Facade的加载过程与原理详解
Sep 22 PHP
PHP实现微信申请退款功能
Oct 01 PHP
PHP使用redis位图bitMap 实现签到功能
Oct 08 PHP
Laravel统一错误处理为JSON的方法介绍
Oct 18 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采集利器 Snoopy 试用心得
2011/07/03 PHP
PHP使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
使用PHP如何实现高效安全的ftp服务器(一)
2015/12/20 PHP
PHP中array_keys和array_unique函数源码的分析
2016/02/26 PHP
javascript判断用户浏览器插件安装情况的代码
2011/01/01 Javascript
Google Map V3 绑定气泡窗口(infowindow)Dom事件实现代码
2013/04/26 Javascript
JavaScript设计模式之装饰者模式介绍
2014/12/28 Javascript
JavaScript通过function定义对象并给对象添加toString()方法实例分析
2015/03/23 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
超漂亮的jQuery图片轮播特效
2015/11/24 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
2018/08/09 jQuery
你知道JavaScript Symbol类型怎么用吗
2020/01/08 Javascript
前端如何实现动画过渡效果
2021/02/05 Javascript
[34:10]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
python高手之路python处理excel文件(方法汇总)
2016/01/07 Python
深入理解Python3中的http.client模块
2017/03/29 Python
Python API len函数操作过程解析
2020/03/05 Python
python实现简单学生信息管理系统
2020/04/09 Python
pandas之分组groupby()的使用整理与总结
2020/06/18 Python
python各种excel写入方式的速度对比
2020/11/10 Python
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
科沃斯机器人官网商城:Ecovacs
2016/08/29 全球购物
波兰最早的运动鞋精品店之一:Street Supply
2019/08/29 全球购物
简述数据库的设计过程
2015/06/22 面试题
业务员薪酬管理制度
2014/01/15 职场文书
大学军训感言1500字
2014/03/09 职场文书
捐书倡议书
2014/08/29 职场文书
2014最新实习证明模板
2014/10/02 职场文书
先进典型事迹材料
2014/12/29 职场文书
2015年社区平安建设工作总结
2015/05/13 职场文书
2015年骨干教师工作总结
2015/05/26 职场文书
2016教师党员学习心得体会
2016/01/21 职场文书
三八红旗手先进事迹材料(2016推荐版)
2016/02/25 职场文书
vue-cli4.5.x快速搭建项目
2021/05/30 Vue.js
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript
在python中读取和写入CSV文件详情
2022/06/28 Python