RSS订阅
登陆
注册

PHP—yield在数据库查询中的内存优化探索

具体情景

  • laravel ORM中的cursor游标
    • cursor方法允许你使用游标遍历数据库,它只执行一次查询。处理大量的数据时,可以大大减少内存的使用量
    • 通过对比cursorget方法,查找到了其中的一点不同,get方法是直接fetchAll返回所有数据,cursor方法是使用yield构建了一个生成器,逐步返回fetch的数据
  • PDO mysql中的查询
    • 一般查询如下:
      $sql = "select * from `user` limit 100000000";
      $stat = $pdo->query($sql);
      $data = $stat->fetchAll();  //mysql buffered直接全部返回给php
      
      var_dump($data);
      
    • 使用yield如下:
      function get(){
          $sql = "select * from `user` limit 100000000";
          $stat = $pdo->query($sql);
          while ($row = $stat->fetch()) { //一个一个地返回给php
              yield $row;
          }
      }
      
      foreach (get() as $row) {
          var_dump($row);
      }
      
  • PDO参数
    • 这个PDO参数,侧面说明了,如果这个参数为ture,MySQL驱动程序将使用MySQL API的缓冲版本。
    • 注意,这个参数只对Mysql起作用,如果要编写可移植的sql代码,请使用fetchAll
    • 查看php手册MYSQL_ATTR_USE_BUFFERED_QUERY

在使用了yield的情况下,内存使用量的确减少了,但是在逐渐使用yield中,内存会逐渐增大,这样的情况与以下函数不一致,下面这个函数的内存使用量将会不变

function getNum() {
    for($i=0; $i < 100000000; $i++) {
        yield $i;
    }
}

结论

在使用fetchfetchAll之前,查找数据结果集还存在于mysql的缓冲区内,而每次yieldfetch配合,才取回一条结果存入内存,这就能解释,为什么内存使用量会逐步增大

而上面的这个getNum函数之所以内存使用量不变,是因为,每次只返回一个数字

未经允许不得转载:php开源优化中文网 - 中国第一档PHP资源分享门户 » PHP—yield在数据库查询中的内存优化探索

赞 (0) 打赏

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏