Zend_Db:fetchAll()或query()/ fetch()用于大量记录

时间:2012-05-05 20:59:17

标签: php zend-framework zend-db

假设我有

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

有两个代码片段可以处理返回的数据,如下所示。

// 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内存中,或者像prepare / execute一样逐个处理?
  2. 假设没有其他选择,C1或C2是更好的选择吗?
  3. 谢谢!

2 个答案:

答案 0 :(得分:16)

你的预感是正确的。至少如果你使用PDO驱动程序, - > fetch()读取未缓冲的结果,而 - > fetchAll()返回大数组中的所有数据。

请注意,如果您使用的是> fetch(),则必须注意您在循环中尝试执行的操作。在您仍然拥有无缓冲的结果集时,无法在同一连接上运行其他查询。

所以,如果你的计划是在循环中更新那些相同的行,你需要找到一种方法来延迟执行更新(通过排队然后以某种方式),直到你退出循环。

答案 1 :(得分:10)

  

要从结果集中检索一行,请使用。的fetch()方法   声明对象。 Reference

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

在上面的示例中,$stmt = $db->query($sql);检索了内存中的resultsetfetch用于从resultset获取循环中的当前行,这会移动游标到下一行,直到它到达resultset的最后一行。

  

要在一个步骤中检索结果集的所有行,请使用   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.

更多信息: Fetching a Row.

我认为fetchAll()更快,因为它在一个步骤中检索所有数据并返回一个数组但消耗更多内存但fetch()消耗更少内存但逐个检索数据。

  

取消操作的API已被取代,允许使用   Zend_Db_Table_Select对象来修改查询。然而   不推荐使用fetchRow()和fetchAll()方法   继续工作而不做任何修改。

更多参考资料 Here.