1

我在基于 ZF1 的应用程序中使用以下代码:

$select = $db->select()->from('table', array('id', 'int', 'float'))->limit(10000, (($i - 1) * 10000));
$data = $select->query();
while ($row = $data->fetch()) {
     # ...
}

此操作在 foreach 循环中发生了大约 800 次。我输出了每遍的内存使用情况,可以看到它每遍增加了大约 5MB。我想这是因为 Zend 显然不会在传递完成后从查询中释放结果。一个简单的 unset 并没有解决问题。使用 fetchAll 也没有改善(或改变)这种情况。

有没有办法从 Zend_Db_Statement_PDO 中释放结果,从而释放它使用的内存?还是您怀疑其他原因?

4

2 回答 2

0

我相信你想这样做:

$sql = "SELECT something FROM random-table-with-an-obscene-large-amount-of-entries";
$res = $db->query($sql);

while ($row = $res->fetch(Zend_Db::FETCH_NUM)) {
  // do some with the data returned in $row
}

Zend_Db::FETCH_NUM - 在数组数组中返回数据。数组由整数索引,对应于查询的选择列表中相应字段的位置。

由于您在每个循环上覆盖 $row,因此应该回收内存。如果你是偏执狂,我相信你可以在循环的底部取消设置($row)。我最近自己没有测试过这个,但是大约一年前我遇到了一个类似的批处理问题,我似乎记得使用过这个解决方案。

于 2013-03-28T20:08:12.520 回答
0

实际上问题隐藏在其他地方:

  • 在循环内部,一些整数结果存储在一个数组中,以便在工作流的稍后计划阶段进行修改。
  • 虽然人们可能期望 PHP 数组很小,但事实并非如此:数组增长得非常快,PHP 数组平均比“预期”大 18 倍。使用数组时要小心,即使您只在其中存储整数!

如果链接的文章有时会消失:

在这篇文章中,我想使用以下脚本作为示例来研究 PHP 数组(以及一般值)的内存使用情况,该脚本创建 100000 个唯一整数数组元素并测量生成的内存使用情况:

$startMemory = memory_get_usage();
$array = range(1, 100000);
echo memory_get_usage() - $startMemory, ' bytes';

你希望它是多少?很简单,一个整数是 8 个字节(在 64 位 unix 机器上并使用 long 类型),你有 100000 个整数,所以你显然需要 800000 个字节。这大约是 0.76 MB。

现在尝试运行上面的代码。这给了我 14649024 字节。是的,你没听错,这是 13.97 MB - 是我们估计的 18 倍。

于 2013-04-05T08:06:55.717 回答