如何解决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 相关文章推荐
计算2000年01月01日起到指定日的天数
Oct 09 PHP
php下实现在指定目录搜索指定类型文件的函数
Oct 03 PHP
支持中文、字母、数字的PHP验证码
May 04 PHP
php结合curl实现多线程抓取
Jul 09 PHP
教你在PHPStorm中配置Xdebug
Jul 27 PHP
PHPStrom中实用的功能和快捷键大全
Sep 23 PHP
简单的pgsql pdo php操作类实现代码
Aug 25 PHP
PHP制作登录异常ip检测功能的实例代码
Nov 16 PHP
Yii2框架数据验证操作实例详解
May 02 PHP
yii2 在控制器中验证请求参数的使用方法
Jun 19 PHP
php生成微信红包数组的方法
Sep 05 PHP
thinkphp5 模型实例化获得数据对象的教程
Oct 18 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
文件系统基本操作类
2006/11/23 PHP
PHP COOKIE设置为浏览器进程
2009/06/21 PHP
用JS实现一个页面多个css样式实现
2008/05/29 Javascript
js数组依据下标删除元素
2015/04/14 Javascript
javascript中 try catch用法
2015/08/16 Javascript
JS 动态加载js文件和css文件 同步/异步的两种简单方式
2016/09/23 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
2017/09/14 Javascript
Vue代码分割懒加载的实现方法
2017/11/23 Javascript
前端天气插件tpwidget使用方法详解
2019/06/24 Javascript
微信小程序简单的canvas裁剪图片功能详解
2019/07/12 Javascript
小程序实现按下录音松开识别语音
2019/11/22 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
Vue 样式切换及三元判断样式关联操作
2020/08/09 Javascript
详解datagrid使用方法(重要)
2020/11/06 Javascript
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
python异常和文件处理机制详解
2016/07/19 Python
利用Python自动监控网站并发送邮件告警的方法
2016/08/24 Python
基于python select.select模块通信的实例讲解
2017/09/21 Python
详解如何利用Cython为Python代码加速
2018/01/27 Python
win7下python3.6安装配置方法图文教程
2018/07/31 Python
python打开windows应用程序的实例
2019/06/28 Python
python manage.py runserver流程解析
2019/11/08 Python
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
Zadig&Voltaire官网:法国时装品牌
2018/01/05 全球购物
台湾网友喜爱的综合型网路购物商城:Yahoo! 奇摩购物中心
2018/03/10 全球购物
初中美术教学反思
2014/01/29 职场文书
高考备战决心书
2014/03/11 职场文书
降消项目实施方案
2014/03/30 职场文书
加入学生会自荐书
2015/03/05 职场文书
感恩老师主题班会
2015/08/12 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
MySQL时间设置注意事项的深入总结
2021/05/06 MySQL
Python深度学习之Pytorch初步使用
2021/05/20 Python
python运算符之与用户交互
2022/04/13 Python