为什么PHP会分配比需要更多的内存?

时间:2016-07-27 21:38:04

标签: php memory mysqli echo

我有一张约70k记录的表,大小约为12 MiB(MB)。

require_once('connection.php');
$sql = "SELECT * FROM BlahBlah";
$result = $con->query($sql);
$data = array();
while($row = $result->fetch_assoc()) {
  $data[] = $row;
}
echo json_encode($data);

当我在PHP中执行fetch_assoc()循环以存储结果并以Json格式将表中的所有行回显到javascript时,我得到Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes)

据我所知,确实需要超过12 MiB的内存,但根据需要分配10倍的内存会让我失望。在此之前我还有另一个查询,它只获取一个151 KB的表。

编辑: 我已经阅读了下面的博客文章,了解为什么PHP需要这么多开销。

一种解决方案是将内存限制设置为无限制,但这似乎是一种可怕的方法,因为我的数据库每天增长~10k记录。 有没有其他方法可以将Json格式的MySQL表中的所有行输出到客户端?我正在从获得的行中生成客户端的谷歌地图标记

1 个答案:

答案 0 :(得分:1)

我和你有同样的问题。我通过手动创建json字符串并尽快通过部分发送给用户来解决它(当然是批量)。

require_once('connection.php');
$sql = "SELECT * FROM BlahBlah";
$result = $con->query($sql);


$json_str = '['; // we will send this to user.
$count = 0; // current number of fetched rows.
$max_count = 100; // max number of rows that we store in memmory bofore sending to client.

$quote = ''; 
// $quote will be used to concatenate json strings
// it's empty only on first iteration

while($row = $result->fetch_assoc()) {
  $json_str .= $quote . json_encode( $row );
  $quote = ',';
  $count++;
  if( $count >= $max_count ){
     echo $json_str;  //send all data that we have for now
     // if you don't want to echo it you can save it to file.

     $json_str = '';  //clear string (prevent memory growing) 
     $count = 0; 
  } 
}
echo $json_str .']';

更新: 还有其他方法可以减少内存使用量

  1. 您可以使用SplFixedArray为$data存储所有行(在我的实践中,它比php Array的效率高20-30%)。
  2. 您可以在将行添加到$ data之前对其进行json编码。这很有趣,但json字符串可能比Array更有效。
  3. 但是这种方法的内存效率更低,速度更慢。