• 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()的实现:

    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端, 前者只是读取了结果集的元信息。

            扯远了: 回到刚才的话题使用mysql_unbuffered_query(), 可以避免内存的立即占用, 如果返回的结果存放到array中也是完全没有问题的, 也不会出现php查询mysql数据量过大时导致内存溢出问题.

  • 相关阅读:
    [算法] 选择排序和插入排序
    [Machine-Learning] 机器学习中的几个度量指标
    [SDN] What is SDN?
    SpringBoot注解大全*(转发:http://www.cnblogs.com/ldy-blogs/p/8550406.html)
    java定时器的使用(Timer)(转发:https://blog.csdn.net/ecjtuxuan/article/details/2093757)
    Quartz使用总结(转发:http://www.cnblogs.com/drift-ice/p/3817269.html)
    Spring IOC/DI和AOP原理(转发:https://www.cnblogs.com/techroad4ca/p/5770073.html)
    Java设计模式之《单例模式》及应用场景(转发:http://www.cnblogs.com/V1haoge/p/6510196.html)
    JDBC注册驱动程序的三种方式
    数据库三范式的简单理解
  • 原文地址:https://www.cnblogs.com/mako/p/4156978.html
Copyright © 2020-2023  润新知