Zend Db: fetchAll () или query ()/fetch () для огромного количества записей

предполагая, что у меня есть

$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 или обрабатывает один за другим, как подготовка/выполнение?
  2. предполагая, что нет другого варианта, C1 или C2 лучше вариант?

спасибо!

2 ответов


ваша догадка верна. По крайней мере, если вы используете драйвер PDO,- >fetch() считывает результаты без буфера, тогда как ->fetchAll() возвращает все данные в большом массиве.

имейте в виду, что если вы используете ->fetch (), вы должны быть осторожны с тем, что вы пытаетесь сделать внутри своего цикла. Вы не можете запускать дополнительные запросы по тому же соединению, пока у вас еще есть небуферизованный результирующий набор.

Итак, если ваш план состоит в том, чтобы обновить те же строки внутри цикла, вам нужно найдите способ отложить выполнение обновлений (путем очереди, а затем каким-то образом), пока вы не выйдете из цикла.


чтобы получить одну строку с результирующий набор, используйте метод fetch() оператор object. ссылка

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

в приведенном выше примере $stmt = $db->query($sql); получены resultset и fetch используется для извлечения текущей строки в цикле из 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..

дополнительные: получение строки..

Я думаю fetchAll() быстрее потому что он извлекает все данные в один шаг и возвращает массив, но потребляет больше памяти, но fetch() потребляет меньше памяти, но извлекает данные один за другим.

API для операций выборки был заменен, чтобы разрешить Zend_db_table_select объект для изменения запроса. Однако устаревшее использование методов fetchRow() и fetchAll() будет продолжают работать без изменений.

Еще Ссылка: здесь.