10

私が持っていると仮定すると

$db is an instance of Zend_Db_Adapter_Abstract and
$sql = 'SELECT blah blah FROM table' will return a huge number of records.

次のように、返されたデータを処理する 2 つのコード フラグメントがあります。

// Code fragment 1 (let's call it C1).
$results = $db->fetchAll($sql);
foreach ($results as $row) {
    // Process $row
}

// Code fragment 2 (let's call it C2).
$stmt = $db->query($sql);
while ($row = $stmt->fetch()) {
    // Process $row
}

私の理解では、C1 は返されたすべてのデータを $results にロードします。そのため、膨大なデータが PHP メモリにロードされます。以下は私の質問です。

  1. C2 はすべてのデータを PHP メモリにロードしますか、それとも準備/実行のように 1 つずつ処理しますか?
  2. 他に選択肢がないと仮定すると、C1 と C2 のどちらがより良い選択肢でしょうか?

ありがとう!

4

2 に答える 2

17

あなたの勘は正しいです。少なくとも PDO ドライバーを使用している場合、->fetch() はバッファリングされていない結果を読み取りますが、->fetchAll() はすべてのデータを大きな配列で返します。

->fetch() を使用している場合は、ループ内で何をしようとしているのかに注意する必要があることに注意してください。バッファリングされていない結果セットがある間は、同じ接続で追加のクエリを実行することはできません。

そのため、ループ内で同じ行を更新する計画がある場合は、ループを終了するまで更新の実行を遅らせる方法を見つける必要があります (キューに入れてから何らかの方法でアップする)。

于 2012-05-05T21:16:32.900 に答える
10

結果セットから 1 行を取得するには、ステートメント オブジェクトの fetch() メソッドを使用します。参照

$sql = 'SELECT blah blah FROM table';
$stmt = $db->query($sql);
while ($row = $stmt->fetch()) {
    // Process $row
}

上記の例では、メモリ内のを$stmt = $db->query($sql);取得し、 からループ内の現在の行をフェッチするために使用されています。これにより、 内の最後の行に到達するまでカーソルが次の行に移動します。resultsetfetchresultsetresultset

結果セットのすべての行を一度に取得するには、fetchAll() メソッドを使用します。これは、ループ内で fetch() メソッドを呼び出し、配列内のすべての行を返すことと同じです。

$sql = 'SELECT blah blah FROM table';
$stmt = $db->query($sql);
$rows = $stmt->fetchAll();
echo $rows[0]['col1']; // The first field/column from the first row

あるいは、使用することができます

....
$table = new Mytable();
// Find a single row Returns a Rowset
$rows = $table->find(1234);

// Find multiple rows Also returns a Rowset
$rows = $table->find(array(1234, 5678));

参照: Zend_Db_Table。.

詳細: 行のフェッチ。.

fetchAll()すべてのデータを 1 ステップで取得して配列を返しますが、より多くのメモリを消費しますが、fetch()消費するメモリは少なくなりますが、データを 1 つずつ取得するため、より高速であると思います。

Zend_Db_Table_Select オブジェクトがクエリを変更できるように、フェッチ操作用の API が置き換えられました。ただし、非推奨の fetchRow() および fetchAll() メソッドの使用法は、変更なしで引き続き機能します。

より多くの参照: ここ.

于 2012-05-05T21:57:21.023 に答える