Я пишу пакетный скрипт и получаю Allowed memory size of 134217728 bytes exhausted
.
Я не понимаю, почему память заполняется. Я попытался отключить переменную $row
, но это ничего не изменило. Вот мой код:
// ... (sql connection) $result = mysql_query("SELECT * FROM large_table"); while ($row = mysql_fetch_array($result)) { echo $row['id'] . PHP_EOL; unset($row); }
с// ... (sql connection) $result = mysql_query("SELECT * FROM large_table"); while ($row = mysql_fetch_array($result)) { echo $row['id'] . PHP_EOL; unset($row); }
(упрощенный код)
Почему память заполняется и как я могу ее избежать?
Примечание: это пакетный скрипт. Это нормально, что я должен обрабатывать такие данные (пройдите 1 миллион строк).
Обновление: из памяти происходит около 400 000-й линии, так что это должно быть что-то в цикле? Я хотел бы избежать необходимости выполнять пейджинг, если это возможно.
Попробуйте использовать http://www.php.net/manual/en/function.mysql-unbuffered-query.php (mysql_unbuffered_query ()), чтобы предотвратить загрузку всей таблицы в память, но все же избегая разбивки на страницы.
Ограничьте свой запрос, например, 1k, и выполните его снова (со смещением), пока не пройдете всю таблицу. Ваш текущий unset не имеет никакого значения, так как $ row перезаписывается каждым при повторении, поэтому вы можете пропустить его.
$chunk_size = 1000; $done = 0; $keep_asking_for_data = true; do{ $result = mysql_query("SELECT * FROM `large_table` LIMIT {$done}, {$chunk_size}"); $num_rows = mysql_num_rows($result); if($num_rows){ $done += $num_rows; while($row = mysql_fetch_assoc($result)){ echo "{$row['id']}\n"; } } else { $keep_asking_for_data = false; } mysql_free_result($result); }while($keep_asking_for_data);
Просто составленный на моей голове, надеюсь, что это работает = D
Если вы используете MySQL, отправьте свои результаты, чтобы вы не исчерпали доступную память. Сам MySQL берет эту память с помощью вашего набора данных базы данных. Посмотрите на следующую ссылку, в частности на LIMIT offset, limit
синтаксис LIMIT offset, limit
SELECT
:
У меня была такая же проблема с большой базой данных. У меня закончилась нехватка памяти, несмотря на то, что она не меняла переменную $ row примерно на 400 000 записей, но небуферизованный запрос исправил ее.
Просто для справки для других (и меня, когда я делаю это снова!), Некоторый код небуферизованного запроса:
$sql = "SELECT SEQ, RECTYPE, ROSTERGRP, EMPNM, EMPNUM, DT, RDUTYCAT, ADUTYCAT FROM " . $tblRosters . " ORDER BY EMPNUM,DT"; $result = mysql_unbuffered_query( $sql, $dbConn ); $svRow = array(); while ( $row = mysql_fetch_array( $result ) ) { // your processing code here } // Unset, close db etc. if you are finished goes here.