`
isiqi
  • 浏览: 16077764 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

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

阅读更多

from:http://www.ideawu.net/blog/archives/581.html

这篇文章主要是从原理, 手册和源码分析在PHP中查询MySQL返回大量结果时, 内存占用的问题, 同时对使用MySQL C API也有涉及.

昨天, 有同事在PHP讨论群里提到, 他做的一个项目由于MySQL查询返回的结果太多(达10万条), 从而导致PHP内存不够用. 所以, 他问, 在执行下面的代码遍历返回的MySQL结果之前, 数据是否已经在内存中了? -

while ($row = mysql_fetch_assoc($result)) {
    // ...
}

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

在查看PHP和MySQL的源码之前, 我注意到PHP手册里有两个功能相近的函数:

mysql_query()
mysql_unbuffered_query()

两个函数的字面意思和说明证实了我的想法, 前一个函数执行时, 会把所有的结果集从Server端读到Client端的缓冲区中, 而后一个则没有, 这就是”unbuffered(未缓冲)”的意思.

那就是说, 如果用mysql_unbuffered_query()执行了一条返回大量结果集的SQL语句, 在遍历结果之前, PHP的内存是没有被结果集占用的. 而用mysql_query()来执行同样的语句的话, 函数返回时, PHP的内存占用便会急剧增加, 立即耗光内存.

如果阅读PHP的相关代码, 可以看到这两个函数的实现上的异同:

/* {{{ proto resource mysql_query(string query [, int link_identifier])
   Sends an SQL query to MySQL */
PHP_FUNCTION(mysql_query)
{
    php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
}
/* }}} */

/* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
   Sends an SQL query to MySQL, without fetching and buffering the result rows */
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()的实现:

if(use_store == MYSQL_USE_RESULT) {
    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端, 前者只是读取了结果集的元信息.

回到PHP, 使用mysql_unbuffered_query(), 可以避免内存的立即占用. 如果在遍历的过程不对结果进行”PHP缓存”(如放到某数组中), 则整个执行过程虽然操作了十万条或者百万条或者更多的数据, 但PHP占用的内存始终是非常小的.

分享到:
评论

相关推荐

    php查询mysql大量数据造成内存不足的解决方法

    本文实例分析了php查询mysql大量数据造成内存不足的解决方法。分享给大家供大家参考。具体分析如下: 一、问题 使用php查询mysql大数据量的时候,程序尚未执行完毕,跳出警告: Fatal error: Allowed memory size ...

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

    主要是从原理, 手册和源码分析在PHP中查询MySQL返回大量结果时, 内存占用的问题, 同时对使用MySQL C API也有涉及.

    PHP查询大量数据内存耗尽问题的解决方法

    从数据库查询大量数据时会出现内容不够的提示: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 这个问题在PHP的官方网站上叫缓冲查询和非缓冲查询(Buffered and Unbuffered queries)。PHP的...

    MYSQL

    10.2.7 MySQL 怎样使用内存 10.2.8 MySQL 怎样锁定数据库表 10.2.9 数据库表级锁定的问题 10.3 使你的数据尽可能小 10.4 MySQL 索引的使用 10.5 存取或更新数据的查询速度 10.5.1 估计...

    MySQL中文参考手册.chm

    10.2.7 MySQL 怎样使用内存 10.2.8 MySQL 怎样锁定数据库表 10.2.9 数据库表级锁定的问题 10.3 使你的数据尽可能小 10.4 MySQL 索引的使用 10.5 存取或更新数据的查询速度 ...

    MySQL中文参考手册

    + 3.4.4 运营一个使用MySQL的Web服务器 o 3.5 MySQL的许可证和技术支持费用 + 3.5.1 付款信息 + 3.5.2 联系信息 o 3.6 商业性支持的类型 + 3.6.1 基本的电子邮件支持 + 3.6.2 扩展的电子邮件支持 + 3.6.3 ...

    php-mysql-engine:用纯PHP编写MySQL引擎

    PHP MySQL引擎PHP MySQL Engine是PHP的库,可让您使用MySQL 5.6的内存模拟来测试数据库驱动的应用程序。 该项目扩展了PDO类,并允许您调用常见的PDO MySQL方法。 它支持各种查询以及某些PDO特定的功能,例如事务和...

    对比PHP对MySQL的缓冲查询和无缓冲查询

    (2)缺点:需要额外的内存来存储这些结果集,而且需要大量的内存,另外,php中用来运行查询的函数会一直到所有的结果都接收才会返回值。 无缓冲查询:会限制你通过严格的顺序访问查询结果。但他不需要额外的内存来...

    MySQL 数据库管理工具 phpMyAdmin 5.1.1 Final 多语中文版.zip

    其中一个更大的优势在于由于 phpMyAdmin 跟其他 PHP 程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的 HTML 页面,也就是于远端管理 MySQL 数据库,方便的建立、修改、删除数据库及资料表。...

    PHP导出MySQL数据到Excel文件(fputcsv)

    经常会碰到需要从数据库中导出数据到Excel文件,用一些开源的类库,比如PHPExcel,确实比较容易实现,但对大量数据的支持很不好,很容易到达PHP内存使用上限。

    phpMyAdmin v4.8.5.zip

    其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由...

    PHP xls通用考试成绩查分系统源码.zip

    无需Mysql等(大部分为非常规数据库),低内存服务器也流畅运行(Mysql可能多耗20%+服务器内存) 6. 低耗网络 现在大多页面单js文件就几百KB,加上图片就更大了。 一个网页往往超过1MB。本查询页一个页面只有30KB左右。 ...

    Zebra_Database:用PHP编写MySQL数据库包装器-开源

    它支持事务,并提供了通过将缓存的数据保存在磁盘上或使用内存缓存来缓存查询结果的方法。 该类提供了全面的调试界面,其中包含有关已执行查询的详细信息:执行时间,返回/受影响的行,找到的行的摘录,错误消息等...

    phpMyAdmin 4.6.6.zip

    其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由...

    Discuz_X2.5四合一版本

    对帖子中的评分、点评数据增加缓存功能,解决评分、点评功能大量使用可能造成PHP内存占用的问题; DIY模块聚合增加限制数目优化,避免复杂检索条件下对数据库造成全表遍历的负载问题; session机制新增关闭可选项...

    WellCMS v1.1.0

    此版无论是使用或是二开,都已将性能发挥至极限了,Centos 7、1核1G内存、Nginx、php7、mysql5.5.6、OPcache、yac,承载亿级数据依然运行飞快。同等配置的环境下,与其他程序对比,wellcms的优势会非常明显。后台...

    学生成绩信息管理系统论文 JSP 完整版

    我们知道,所谓的数据库就是一些结构化的数据的联合体,要提供对这些数据的存取、增加、修改、删除或更加复杂的数据抽取等操作,需要有一个支撑系统,这就是数据库管理系统(DBMS),MySQL完全具有这方面的功能。...

Global site tag (gtag.js) - Google Analytics