如何解决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 相关文章推荐
php+mysql开源XNA 聚合程序发布 下载
Jul 13 PHP
php 常用字符串函数总结
Mar 15 PHP
php adodb连接带密码access数据库实例,测试成功
May 14 PHP
PHP5.2中date()函数显示时间与北京时间相差8小时的解决办法
May 28 PHP
php 多线程上下文中安全写文件实现代码
Dec 28 PHP
深入Apache与Nginx的优缺点比较详解
Jun 17 PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
Jul 08 PHP
PHP 魔术变量和魔术函数详解
Feb 25 PHP
解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法
Oct 23 PHP
浅谈PHP错误类型及屏蔽方法
May 27 PHP
php 算法之实现相对路径的实例
Oct 17 PHP
PHP工厂模式的日常使用
Mar 20 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
如何让搜索引擎抓取AJAX内容解决方案
2014/08/25 PHP
使用jscript实现二进制读写脚本代码
2008/06/09 Javascript
ExtJS 2.0 实用简明教程之布局概述
2009/04/29 Javascript
IE iframe的onload方法分析小结
2010/01/07 Javascript
javascript中callee与caller的用法和应用场景
2010/12/08 Javascript
通过action传过来的值在option获取进行验证的方法
2013/11/14 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
浅谈JavaScript字符串拼接
2015/06/25 Javascript
JS简单模拟触发按钮点击功能的方法
2015/11/30 Javascript
AngularJs  Creating Services详解及示例代码
2016/09/02 Javascript
AngularJS中过滤器的使用与自定义实例代码
2016/09/17 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
jQuery实现web页面樱花坠落的特效
2017/06/01 jQuery
js CSS3实现卡牌旋转切换效果
2017/07/04 Javascript
使用 vue 实现灭霸打响指英雄消失的效果附demo
2019/05/06 Javascript
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
编写Python脚本来获取mp3文件tag信息的教程
2015/05/04 Python
python实用代码片段收集贴
2015/06/03 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
2016/08/30 Python
python 批量添加的button 使用同一点击事件的方法
2019/07/17 Python
基于Python实现ComicReaper漫画自动爬取脚本过程解析
2019/11/11 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
Python原始套接字编程实例解析
2020/01/29 Python
使用css创建三角形 使用CSS3创建3d四面体原理及代码(html5实践)
2013/01/06 HTML / CSS
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
Linux操作面试题
2012/05/16 面试题
护士自我鉴定范文
2013/10/06 职场文书
小学体育教学反思
2014/01/31 职场文书
超市中秋节活动方案
2014/02/12 职场文书
市场总监岗位职责
2015/02/11 职场文书
2019年感恩励志演讲稿(收藏备用)
2019/09/11 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
JavaWeb 入门篇:创建Web项目,Idea配置tomcat
2021/07/16 Java/Android
为什么MySQL选择Repeatable Read作为默认隔离级别
2021/07/26 MySQL
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB
浅谈为什么我的 z-index 又不生效了
2022/07/15 HTML / CSS