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 相关文章推荐
也谈截取首页新闻 - 范例
Oct 09 PHP
调整优化您的LAMP应用程序的5种简单方法
Jun 26 PHP
PHP中“简单工厂模式”实例代码讲解
Sep 04 PHP
PHP curl 并发最佳实践代码分享
Sep 05 PHP
PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等)
Apr 21 PHP
php+MySQL判断update语句是否执行成功的方法
Aug 28 PHP
php+mysql实现用户注册登陆的方法
Jan 03 PHP
Yii2隐藏frontend/web和backend/web的方法
Dec 12 PHP
Yii 2.0实现联表查询加搜索分页的方法示例
Aug 02 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
golang实现php里的serialize()和unserialize()序列和反序列方法详解
Oct 30 PHP
php与阿里云短信接口接入操作案例分析
May 27 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
基于mysql的bbs设计(四)
2006/10/09 PHP
谈谈新手如何学习PHP
2006/12/14 PHP
解决file_get_contents无法请求https连接的方法
2013/12/17 PHP
php采用curl实现伪造IP来源的方法
2014/11/21 PHP
smarty实现多级分类的方法
2014/12/05 PHP
jQuery Mobile + PHP实现文件上传
2014/12/12 PHP
PHP7.0安装笔记整理
2015/08/28 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
2019/05/13 PHP
jquery 分页控件实现代码
2009/11/30 Javascript
Script的加载方法小结
2011/01/12 Javascript
基于jQuery的获取标签名的代码
2012/07/16 Javascript
Flexigrid在IE下不显示数据的处理的解决方法
2013/10/24 Javascript
JS 打印功能代码可实现打印预览、打印设置等
2014/10/31 Javascript
JavaScript实现更改网页背景与字体颜色的方法
2015/02/02 Javascript
jQuery中hover方法和toggle方法使用指南
2015/02/27 Javascript
jQuery选择器总结之常用元素查找方法
2016/08/04 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
JavaScript 中Date对象的格式化代码方法汇总
2017/09/06 Javascript
Node.js中读取TXT文件内容fs.readFile()用法
2018/10/10 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
[03:03]DOTA2校园争霸赛 济南城市决赛欢乐发奖活动
2013/10/21 DOTA
Python实现单词拼写检查
2015/04/25 Python
Flask框架WTForm表单用法示例
2018/07/20 Python
python判断输入日期为第几天的实例
2018/11/13 Python
numpy linalg模块的具体使用方法
2019/05/26 Python
Python 运行.py文件和交互式运行代码的区别详解
2019/07/02 Python
python Django 创建应用过程图示详解
2019/07/29 Python
加拿大最大的书店:Indigo
2017/01/01 全球购物
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
Sql面试题
2013/03/20 面试题
在浏览器端如何得到服务器端响应的XML数据
2012/11/24 面试题
设计总监岗位职责
2013/12/07 职场文书
图书室管理制度
2014/01/19 职场文书
会计求职自荐信
2014/06/20 职场文书
中小学生学籍证明
2014/10/25 职场文书
Redis分布式锁的7种实现
2022/04/01 Redis