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 相关文章推荐
PHP5新特性: 更加面向对象化的PHP
Nov 18 PHP
php 404错误页面实现代码
Jun 22 PHP
PHP-CGI进程CPU 100% 与 file_get_contents 函数的关系分析
Aug 15 PHP
比file_get_contents稳定的curl_get_contents分享
Jan 11 PHP
ThinkPHP模板引擎之导入资源文件方法详解
Jun 18 PHP
CodeIgniter针对数据库的连接、配置及使用方法
Mar 03 PHP
PHP简单创建压缩图的方法
Aug 24 PHP
php面向对象的用户登录身份验证
Jun 08 PHP
php7函数,声明,返回值等新特性介绍
May 25 PHP
php实现微信公众号企业转账功能
Oct 01 PHP
PHP Swoole异步MySQL客户端实现方法示例
Oct 24 PHP
PHP7移除的扩展和SAPI
Mar 09 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
实现了一个PHP5的getter/setter基类的代码
2007/02/25 PHP
php中通过Ajax如何实现异步文件上传的代码实例
2011/05/07 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法
2016/09/30 PHP
PHP 的Opcache加速的使用方法
2017/12/29 PHP
PHP实现简单的计算器
2020/08/28 PHP
php解析非标准json、非规范json的方式实例
2020/12/10 PHP
Javascript异步表单提交,图片上传,兼容异步模拟ajax技术
2010/05/10 Javascript
javascript移动设备Web开发中对touch事件的封装实例
2014/06/05 Javascript
招聘网站基于jQuery实现自动刷新简历
2015/05/10 Javascript
神奇!js+CSS+DIV实现文字颜色渐变效果
2016/03/16 Javascript
JQuery DIV 动态隐藏和显示的方法
2016/06/23 Javascript
微信小程序--onShareAppMessage分享参数用处(页面分享)
2017/04/18 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
express默认日志组件morgan的方法
2018/04/05 Javascript
实例详解Vue项目使用eslint + prettier规范代码风格
2018/08/20 Javascript
React Hooks的深入理解与使用
2018/11/12 Javascript
layui实现多图片上传并限制上传的图片数量
2019/09/26 Javascript
在node环境下parse Smarty模板的使用示例代码
2019/11/15 Javascript
JavaScript canvas动画实现时钟效果
2020/02/10 Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
2020/05/23 Javascript
Python完全新手教程
2007/02/08 Python
简单介绍Python中的JSON使用
2015/04/28 Python
python的scikit-learn将特征转成one-hot特征的方法
2018/07/10 Python
预订奥兰多和佛罗里达州公园门票:FloridaTix
2018/01/03 全球购物
介绍一下sql server的安全性
2014/08/10 面试题
党支部公开承诺书
2014/03/28 职场文书
ktv筹备计划书
2014/05/03 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
房屋出租委托书格式
2014/09/23 职场文书
民事申诉状范本
2015/05/20 职场文书
辩护词范文大全
2015/05/21 职场文书
redis cluster支持pipeline的实现思路
2021/06/23 Redis
Go并发4种方法简明讲解
2022/04/06 Golang
MySQL 外连接语法之 OUTER JOIN
2022/04/09 MySQL
SQL Server数据库的三种创建方法汇总
2023/05/08 MySQL