Zend_Db: fetchAll() or query()/fetch() for a huge number of records

peidiam picture peidiam · May 5, 2012 · Viewed 20.3k times · Source

Assuming I have

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

There are two code fragments to process the returned data as follows.

// 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
}

My understanding is that C1 will load all returned data to $results. So, a huge data is loaded to PHP memory. Below are my questions.

  1. Does C2 load all data to PHP memory or does it process one by one like prepare/execute?
  2. Assuming there is no other option, is C1 or C2 a better option?

Thanks!

Answer

timdev picture timdev · May 5, 2012

Your hunch is correct. At least if you're using the PDO driver, ->fetch() reads the results unbuffered, whereas ->fetchAll() returns all the data in a big array.

Be aware that if you're using ->fetch(), you have to be careful about what you try to do inside your loop. You can't run additional queries on the same connection while you've still got an unbuffered result set.

So, if your plan is to update those same rows inside the loop, you'll need to find a way to delay executing the updates (by queuing then up somehow) until you've exited the loop.