bst365最新正规买球

PHP查询MySQL海量数据内存占用分析
  • 更新时间:2024-07-19 03:43:35
  • 网站建设
  • 发布时间:1年前
  • 425

PHP查询MySQL大量数据的内存占用分析

本文主要从原理、手册和源码分析PHP查询MySQL时返回大量结果的内存占用问题,同时也涉及到MySQL C API的使用。

昨天有同事在PHP讨论组提到,他在做的一个项目,MySQL查询返回的结果太多(最多10万条),导致PHP内存不足。于是,他问,执行完下面的代码遍历返回MySQL结果之前,数据是否已经在内存中了? -

while($row=mysql_fetch_assoc($result)){

//.

}

当然,针对这类问题的优化方法有很多。不过,就这个问题,我首先想到的是MySQL是经典的C/S(Client/Server,客户端/服务器)模型。在遍历结果集之前,底层实现可能已经通过网络(假设使用TCP/IP)将所有数据读到客户端缓冲区,还有一种可能是数据还在服务端的发送缓冲区中,并且已经没有传送给客户端。

之前看PHP和MySQL的源码,注意到PHP手册:中有两个功能相似的函数

mysql_查询()

mysql_unbuffered_query()

这两个函数的字面意思和描述证实了我的想法。执行前一个函数时,会将服务器端的所有结果集读取到客户端缓冲区,而后一个函数则不会。这就是“无缓冲(unbuffered)”的意思。

也就是说,如果使用mysql_unbuffered_query()执行一个返回大结果集的SQL语句,在遍历结果之前,PHP的内存是不会被结果集占用的。如果用mysql_query()执行同样的语句,函数返回,PHP的内存占用会急剧增加,内存会马上被耗尽。

如果你看过PHP的相关代码,就可以看出这两个函数实现的异同:

/*{{{protoresourcemysql_query(stringquery[,intlink_identifier])

向MySQL 发送SQL 查询*/

PHP_FUNCTION(mysql_query)

{

php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU,MYSQL_STORE_RESULT); 

}

/*}}}*/

/*{{{protoresourcemysql_unbuffered_query(stringquery[,intlink_identifier]) 

向MySQL 发送SQL 查询,不获取和缓冲结果行*/

PHP_FUNCTION(mysql_unbuffered_query)

{

php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU,MYSQL_USE_RESULT);

}

/*}}}*/

两个函数都调用了php_mysql_do_query(),只是第二个参数不同,MYSQL_STORE_RESULT和MYSQL_USE_RESULT。查看php_mysql_do_query()的实现:

如果(使用存储==MYSQL_USE_RESULT){

mysql_result=mysql_use_result(mysql-conn);

}别的{

mysql_result=mysql_store_result(mysql-conn);

}

mysql_use_result() 和mysql_store_result() 是MySQL C API 函数。这两个C API函数的区别在于,后者是从MySQL Server读取所有的结果集到Client,而前者只读取结果集的元信息。

回到PHP,使用mysql_unbuffered_query() 来避免直接内存占用。如果在遍历过程中结果没有被“PHP缓存”(比如放在一个数组中),虽然整个执行过程操作了10万条或者百万条或者更多的数据,但是PHP占用的内存总是很小的。

标签: 北京网站制作高端网站建设

我们专注高端建站,小程序开发、软件系统定制开发、BUG修复、物联网开发、各类API接口对接开发等。十余年开发经验,每一个项目承诺做到满意为止,多一次对比,一定让您多一份收获!

本文章出于推来客官网,转载请表明原文地址://www.tlkjt.com/web/13828.html

扫码联系客服

3985758

回到顶部