php查询mysql返回大量数据结果集导致内存溢出的解决方法
web开发中如果遇到php查询mysql返回大量数据导致内存溢出、或者内存不够用的情况那就需要看下MySQL C API的关联,那么究竟是什么导致php查询mysql返回大量数据时内存不够用情况?
答案是: mysql_query 和 mysql_unbuffered_query 两个函数
首先来分析一个典型的实例:在执行下面的代码的时候就会导致php请求mysql返回结果太多(10W以上)导致PHP内存不够用。
while ($row = mysql_fetch_assoc($result))
{
// …
}
对于上面的问题来讲,首先要从mysql的原理上来分析 MySQL是经典的C/S(Client/Server, 客户端/服务器)模型, 在遍历结果集之前, 底层的实现可能已经把所有的数据通过网络(假设使用TCP/IP)读到了Client的缓冲区, 也有另一种可能, 就是数据还在Server端的发送缓冲区里, 并没有传给Client。
通过查看php和mysql的源码中发现两个相似的mysql函数:mysql_query() 和mysql_unbuffered_query(),
发现前一个函数执行时, 会把所有的结果集从Server端读到Client端的缓冲区中, 而后一个则没有, 这就是“unbuffered(未缓冲)”的意思。也就是说, 如果用mysql_unbuffered_query() 执行了一条返回大量结果集的SQL语句, 在遍历结果之前, PHP的内存是没有被结果集占用的。 而用mysql_query() 来执行同样的语句的话, 函数返回时, PHP的内存占用便会急剧增加, 立即耗光内存。
PHP_FUNCTION(mysql_query)
{
php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
}
PHP_FUNCTION(mysql_unbuffered_query)
{
php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
}
两个函数都调用了php_mysql_do_query(), 只差了第2个参数的不同, MYSQL_STORE_RESULT和MYSQL_USE_RESULT. 再看php_mysql_do_query()的实现:
{
mysql_result=mysql_use_result(&mysql->conn);
}
else
{
mysql_result=mysql_store_result(&mysql->conn);
}
mysql_use_result()和mysql_store_result()是MySQL的C API函数, 这两个C API函数的区别就是后者把结果集从MySQL Server端全部读取到了Client端, 前者只是读取了结果集的元信息。
扯远了: 回到刚才的话题使用mysql_unbuffered_query(), 可以避免内存的立即占用, 如果返回的结果存放到array中也是完全没有问题的, 也不会出现php查询mysql数据量过大时导致内存溢出问题.
php查询mysql返回大量数据结果集导致内存溢出的解决方法的更多相关文章
- 返回Json数据浏览器带上<pre></pre>标签解决方法
问题: 当后台获取到前台传来的文件时(例如上传功能, 导入功能), 返回类型为application/json, 这个时候响应到前端的JSON格式的数据格式可能是: <pre style=&q ...
- mysql5.x升级到mysql5.7后导入之前数据库date出错的快速解决方法【mysql低版本数据导入到高版本出错的解决方法】
mysql5.x升级至mysql5.7后导入之前数据库date出错,这是由于MySQL的sql_mode的影响,解决方法如下所示: [具体参考:mysql的sql_mode详解]修改mysql5.7的 ...
- Thinkphp解决phpExcel导出数据量大导致内存溢出
工作需要导出几万的数据量.操作比较频繁.之前数据在七八千是数据导出很慢.phpExcel是方便但是性能一般.现在改为使用csv导出数据:可以缓解内存压力,一次导出两三万是没问题的.当然服务器内存给力, ...
- Mysql遍历大表(Mysql大量数据读取内存溢出的解决方法)
mysql jdbc默认把select的所有结果全部取回,放到内存中,如果是要遍历很大的表,则可能把内存撑爆. 一种办法是:用limit,offset,但这样你会发现取数据的越来越慢,原因是设置了of ...
- mysql安装版多次安装导致安装失败的解决方法(windows)(直接使用免安装方法)
https://www.cnblogs.com/feilongblog/p/mysql_install_init.html 测试成功 要点:mysqld install MySQL --default ...
- 查询返回JSON数据结果集
查询返回JSON数据结果集 设计目标: 1)一次性可以返回N个数据表的JSON数据 2)跨数据库引擎 { "tables": [ { "cols": [ { & ...
- PDO 查询mysql返回字段整型变为String型解决方法
PDO 查询mysql返回字段整型变为String型解决方法 使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...
- PDO 查询mysql返回字段int变为String型解决方法
PDO 查询mysql返回字段int变为String型解决方法使用PDO查询mysql数据库时,执行prepare,execute后,返回的字段数据全都变为字符型. 例如id在数据库中是Int的,查询 ...
- Atitit.列表页面and条件查询的实现最佳实践(1)------设置查询条件and提交查询and返回json数据
Atitit.列表页面and条件查询的实现最佳实践(1)------设置查询条件and提交查询and返回json数据 1. 1. 配置条件字段@Conditional 1 1 2. 2. 配置条件字段 ...
随机推荐
- 数据库引擎InnoDB和MyISAM区别
MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...
- 编写高效SQL语句(转)
转至http://blog.csdn.net/u012150457/article/details/41846299 一.编写高效SQL语句 1) 选择最有效的表名顺序(仅适用于RBO模式) ORAC ...
- P2762 太空飞行计划问题(网络流24题之一)
题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的 ...
- Stream My Contest UVA - 11865(带权最小树形图+二分最小值最大化)
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...
- Docker学习笔记四:Docker镜像、容器管理工具shipyard
一.拉取以下几种镜像: docker pull alpineshipyard/shipyarddocker pull swarm docker pull shipyard/shipyarddocker ...
- 【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)
[BZOJ2432][NOI2011]兔农(数论,矩阵快速幂) 题面 BZOJ 题解 这题\(75\)分就是送的,我什么都不想写. 先手玩一下,发现每次每次出现\(mod\ K=1\)的数之后 把它减 ...
- Sort Integers II
Given an integer array, sort it in ascending order. Use quick sort, merge sort, heap sort or any O(n ...
- BZOJ1069 [SCOI2007]最大土地面积 【凸包 + 旋转卡壳】
题目链接 BZOJ1069 题解 首先四个点一定在凸包上 我们枚举对角线,剩下两个点分别是两侧最远的点 可以三分,复杂度\(O(n^2logn)\) 可以借鉴旋转卡壳的思想,那两个点随着对角线的一定单 ...
- SCOI2014极水的题解- -
话说SCOI都考了1个月了,终于拿出决心把题解补完了,但都说了是极水的题解,大家就看着玩吧- - DAY1 T1:目标是找最长不降子序列,先就有一个比较显然的结论,就是假如我们要拔高区间[L, R], ...
- 使用expect实现自动登录的脚本
使用expect实现自动登录的脚本,网上有很多,可是都没有一个明白的说明,初学者一般都是照抄.收藏.可是为什么要这么写却不知其然.本文用一个最短的例子说明脚本的原理. 脚本代码如下: ######## ...