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 がクエリから結果を明らかに解放しないためだと思います。単純な設定解除では問題は解決しませんでした。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 を上書きするため、メモリを再利用する必要があります。あなたが妄想的であれば、ループの最後で unset($row) できると思います。私は最近これを自分でテストしていませんが、約1年前に同様のバッチ問題に遭遇し、このソリューションを使用したことを思い出したようです.

于 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';

どれくらいになると思いますか?シンプルで、1 つの整数は 8 バイト (64 ビット UNIX マシンで long 型を使用) であり、100000 の整数を取得したため、明らかに 800000 バイトが必要になります。それは 0.76 MB のようなものです。

上記のコードを実行してみてください。これにより、14649024 バイトが得られます。はい、ご存じのとおり、13.97 MB であり、見積もりの​​ 18 倍です。

于 2013-04-05T08:06:55.717 に答える