如何解决PHP使用mysql_query查询超大结果集超内存问题


Posted in PHP onMarch 14, 2016

再使用mysql_query查询超大结果集的时候会出现超出内存限制的致命错误,这是因为mysql_query采用的是查询全部结果然后把结果集全部缓存到内存中的方式。

mysql的查询还提供了另外一种查询方式,函数名为mysql_unbuffered_query,这个函数采用的是查出结果后立即操作结果集,并不会把结果集缓存到内存中,这样就避免了超出内存的情况发生。但是使用这个方法的代价就是不能再查询的时候使用获取总行之类的方法,因为这种方法是便查询边返回结果。同时在使用该方法的时候不能在同一数据库链接上执行其他的操作,想要执行其他操作的时候必须先终止当前操作,释放所有未缓存的sql查询所产生的结果行,或者重新实例化一个数据库连接,使用新链接进行其他操作。

以下是使用缓存和不使用缓存的对比(所查询的表中有1000多万行数据):

function selecttest()
{
try {
$pdo = new PDO("mysql:host=localhost;dbname=test", 'root', '123456');
// 不使用缓存结果集方式
// $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$sth = $pdo->prepare('select * from test');
$sth->execute();
echo '最初占用内存大小:' . memory_get_usage() . "\n";
$i = 0;
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
$i += 1;
if ($i > 10) {
break;
}
sleep(1);
print_r($result);
echo '占用内存大小:' . memory_get_usage() . "\n";
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

上面使用到的是缓存所有结果集的方式,运行该函数时将会报超内存的错误,如下所示:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 204800000 bytes) in E:\ProgramDevelopment\RuntimeEnvironment\xampp\htdocs\test\test.php on line 57

Call Stack:

0.0005 135392 1. {main}() E:\ProgramDevelopment\RuntimeEnvironment\xampp\htdocs\test\test.php:0
0.0005 135568 2. test->selecttest() E:\ProgramDevelopment\RuntimeEnvironment\xampp\htdocs\test\test.php:86
0.0055 142528 3. PDOStatement->execute() E:\ProgramDevelopment\RuntimeEnvironment\xampp\htdocs\test\test.php:57

在执行$sth->execute();时超出内存限制;

将// $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);这行的注释去掉后将使用不缓存结果集的方式,运行该函数将输出以下内容:

最初占用内存大小:144808

Array
(
[id] => 1
[a] => v
[b] => w
[c] => i
)

占用内存大小:145544

Array
(
[id] => 2
[a] => b
[b] => l
[c] => q
)

占用内存大小:145544

Array
(
[id] => 3
[a] => m
[b] => p
[c] => h
)

占用内存大小:145536

Array
(
[id] => 4
[a] => j
[b] => i
[c] => b
)

占用内存大小:145536

Array
(
[id] => 5
[a] => q
[b] => g
[c] => g
)

占用内存大小:145536

可以看到,使用不缓存结果集的方式获取一行结果所占用的内存是极少的。这样就结局了超出内存限制的问题。

PHP 相关文章推荐
ezSQL PHP数据库操作类库
May 16 PHP
PHP内核介绍及扩展开发指南―基础知识
Sep 11 PHP
解析php通过cookies获取远程网页的指定代码
Jun 25 PHP
浅析php fwrite写入txt文件的时候用 \r\n不能换行的问题
Aug 06 PHP
php curl post 时出现的问题解决
Jan 30 PHP
php实现图片添加水印功能
Feb 13 PHP
yii的CURD操作实例详解
Dec 04 PHP
PHP实现将视频转成MP4并获取视频预览图的方法
Mar 12 PHP
php调整服务器时间的方法
Apr 03 PHP
php+redis在实际项目中HTTP 500: Internal Server Error故障排除
Feb 05 PHP
php unlink()函数使用教程
Jul 12 PHP
PHP判断一个变量是否为整数、正整数的方法示例
Sep 11 PHP
Zend Framework教程之资源(Resources)用法实例详解
Mar 14 #PHP
PHP访问数据库集群的方法小结
Mar 14 #PHP
php 无限级分类 获取顶级分类ID
Mar 13 #PHP
PHP实现文件上传与下载实例与总结
Mar 13 #PHP
PHP+shell脚本操作Memcached和Apache Status的实例分享
Mar 11 #PHP
PHP批量去除BOM头内容信息代码
Mar 11 #PHP
PHP中调用C/C++制作的动态链接库的教程
Mar 10 #PHP
You might like
php curl_init函数用法
2014/01/31 PHP
win7 64位系统 配置php最新版开发环境(php+Apache+mysql)
2014/08/15 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
PHP常用算法和数据结构示例(必看篇)
2017/03/15 PHP
PHP中创建和编辑Excel表格的方法
2018/09/13 PHP
Javascript开发包大全整理
2006/12/22 Javascript
用jscript启动sqlserver
2007/06/21 Javascript
JQuery 国际象棋棋盘 实现代码
2009/06/26 Javascript
JS焦点图切换,上下翻转
2011/05/12 Javascript
不使用浏览器运行javascript代码的方法
2013/07/24 Javascript
js的[defer]和[async]属性
2014/11/24 Javascript
js组件SlotMachine实现图片切换效果制作抽奖系统
2016/04/17 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
vue element 中的table动态渲染实现(动态表头)
2019/11/21 Javascript
在Django中进行用户注册和邮箱验证的方法
2016/05/09 Python
Python 爬虫学习笔记之正则表达式
2016/09/21 Python
Python基于ThreadingTCPServer创建多线程代理的方法示例
2018/01/11 Python
python 获取页面表格数据存放到csv中的方法
2018/12/26 Python
对python for 文件指定行读写操作详解
2018/12/29 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
python用线性回归预测股票价格的实现代码
2019/09/04 Python
python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析
2019/10/14 Python
Python3常见函数range()用法详解
2019/12/30 Python
Python装饰器用法与知识点小结
2020/03/09 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
RUIFIER官网:英国奢侈高级珠宝品牌
2020/06/12 全球购物
物理教育专业毕业生推荐信
2013/11/03 职场文书
安全教育心得体会
2013/12/29 职场文书
校本教研工作制度
2014/01/22 职场文书
咖啡蛋糕店创业计划书
2014/01/28 职场文书
《小石潭记》教学反思
2014/02/13 职场文书
函授毕业生自我鉴定范文
2014/03/25 职场文书
庆国庆活动总结
2014/08/28 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
2014年协会工作总结
2014/11/22 职场文书
同意落户证明
2015/06/19 职场文书