文章主要从原理、手册、源码等方面分析了PHP查询MySQL返回大量结果时内存占用的问题,还涉及到了使用方法,跟随小编一起来看看吧!
昨天,同事在 PHP 讨论组里提到,他正在做的一个项目,MySQL 查询返回的结果太多(多达 10 万条),导致 PHP 内存耗尽。于是,他问,在执行下面代码遍历返回的 MySQL 结果之前,数据是否已经在内存中了呢?——
复制代码如下:
while($row=($)){
//...
当然,有很多方法可以优化这个问题。但是,就这个问题而言,我首先想到的是,MySQL 是经典的 C/S(客户端/服务器)模型,在遍历结果集之前,底层实现可能已经通过网络(假设使用 TCP/IP)将所有数据读入缓冲区。还有一种可能是,数据还在端的发送缓冲区中,没有被发送出去。
在查看PHP和MySQL的源代码之前,注意到PHP手册中有两个功能类似的函数:
复制代码如下:
()
ry()
两个函数的字面意思和描述证实了我的想法,前一个函数执行时,会将所有结果集从尾部读取到尾部缓冲区,而后一个函数则不会,这就是“()”的意思。
也就是说,如果你使用ry()执行一个返回很大结果集的SQL语句,在遍历结果之前,PHP的内存还未被结果集占用。如果你使用()执行同样的语句,当函数返回时,PHP的内存占用会急剧增加,并立即耗尽内存。
如果你阅读相关的PHP代码,你就会发现这两个函数实现的相同点和不同点:
复制代码如下:
()
(,);
(瑞)
(,);
两个函数都调用了(),唯一的区别就是第二个参数,和。我们来看看()的实现:
复制代码如下:
如果(==){
=(&mysql-> conn);
}别的{
=(&mysql-> conn);
()和()都是MySQL的CAPI函数,这两个CAPI函数的区别在于后者是把整个结果集从客户端读取到客户端,而前者只是读取结果集的元信息。
回到PHP,使用ry()可以避免立即占用内存,如果遍历过程中不将结果“缓存”(比如放入数组)的话,即使整个执行过程操作十万、一百万甚至更多的数据,PHP占用的内存总是很小的。
我查看了PHP查询大量MySQL数据时的内存使用情况分析,还查看了:
扫一扫在手机端查看
-
Tags : PHP查询MySQL大量数据的时候内存占用分析
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。