如何解决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编程语言开发动态WAP页面
Oct 09 PHP
php 变量定义方法
Jun 14 PHP
PHP中spl_autoload_register函数的用法总结
Nov 07 PHP
利用谷歌 Translate API制作自己的翻译脚本
Jun 04 PHP
php中header跳转使用include包含解决参数丢失问题
May 08 PHP
php数组比较实现查找连续数的方法
Jul 29 PHP
Symfony2在Nginx下的配置方法图文教程
Feb 04 PHP
PHP5.5安装PHPRedis扩展及连接测试方法
Jan 22 PHP
php图像验证码生成代码
Jun 08 PHP
详解Yaf框架PHPUnit集成测试方法
Dec 27 PHP
PHP排序二叉树基本功能实现方法示例
May 26 PHP
Laravel框架处理用户的请求操作详解
Dec 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
php中将汉字转换成拼音的函数代码
2012/09/08 PHP
linux命令之调试工具strace的深入分析
2013/06/03 PHP
php递归使用示例(php递归函数)
2014/02/14 PHP
如何运行/调试你的PHP代码
2020/10/23 PHP
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
jquery动态加载select下拉框示例代码
2013/12/10 Javascript
javascript中普通函数的使用介绍
2013/12/19 Javascript
JavaScript实现弹出子窗口并传值给父窗口
2014/12/18 Javascript
使用javascript实现雪花飘落的效果
2015/01/13 Javascript
JSON与XML的区别对比及案例应用
2016/11/11 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
vue权限路由实现的方法示例总结
2018/07/29 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
2021/02/07 Vue.js
[03:46]DOTA2英雄基础教程 维萨吉
2013/12/11 DOTA
python计算最大优先级队列实例
2013/12/18 Python
Django中使用locals()函数的技巧
2015/07/16 Python
20招让你的Python飞起来!
2016/09/27 Python
Python标准库之collections包的使用教程
2017/04/27 Python
python opencv之分水岭算法示例
2018/02/24 Python
Python可视化mhd格式和raw格式的医学图像并保存的方法
2019/01/24 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
美国隐形眼镜销售网站:ContactsDirect
2017/10/28 全球购物
Craghoppers德国官网:户外和旅行服装
2020/02/14 全球购物
汽车运用工程系毕业生自荐信
2013/12/27 职场文书
入党转预备思想汇报
2014/01/07 职场文书
护理个人求职信范文
2014/01/08 职场文书
母婴店促销方案
2014/03/05 职场文书
水毁工程实施方案
2014/04/01 职场文书
群众路线党员自我评议范文2014
2014/09/24 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
幼儿园见习总结
2015/06/23 职场文书
教师培训简讯
2015/07/20 职场文书
2016大学优秀学生干部事迹材料
2016/03/01 职场文书
大学生各类奖学金申请书
2019/06/24 职场文书
「SHOW BY ROCK!!」“雫シークレットマインド”组合单曲MV公开
2022/03/21 日漫