Утечка памяти в PHP при получении большого набора данных из MySQL - PullRequest
4 голосов
/ 07 декабря 2011

Когда я выполняю следующий код для пользовательской таблицы из примерно 60 000 записей:

mysql_connect("localhost", "root", "");
mysql_select_db("test");

$result = mysql_query("select * from users");

while ($row = mysql_fetch_object($result)) {
  echo(convert(memory_get_usage(true))."\n");
}


function convert($size) {
  $unit=array('b','kb','mb','gb','tb','pb');
  return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

Я получаю следующую ошибку:

PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes)

Есть какие-нибудь мысли о том, как избежать того, чтобы скрипт занимал дополнительную память при каждом прохождении цикла? В моем собственном коде я пытаюсь обеспечить загрузку CSV для большого набора данных с небольшой предварительной обработкой PHP.

Пожалуйста, не рекомендуется увеличивать ограничение памяти PHP - это плохая идея, и, что более важно, все равно создаст восходящую границу того, насколько большой набор данных может быть обработан с помощью этой техники.

Ответы [ 3 ]

1 голос
/ 07 декабря 2011

mysql_query буферизует весь результирующий набор в PHP памяти. Это удобно и вообще очень быстро, но вы испытываете недостаток в ней.

mysql_unbuffered_query () существует. Он не захватить весь набор результатов сразу. Она захватывает маленькие кусочки в то время, когда вы выборка строк из результирующего набора.

1 голос
/ 07 декабря 2011

Я не уверен на 100%, решит ли это вашу проблему, но вы рассматривали возможность использования PDO ? У этого есть несколько преимуществ; Вы можете прочитать больше о них здесь . Если вы пойдете в этом направлении, то возникнет похожий вопрос об использовании памяти здесь .

0 голосов
/ 07 декабря 2011

У меня была похожая проблема.Чтобы заставить его работать, я создал временный файл (вы можете использовать хеш или что-то подобное для записи имени).

  • Потяните 10000 строк и поместите их в файл (темп).Поместите его в временный CSV-файл.
  • Перезагрузите страницу (используя заголовок с конкретными параметрами / сеансом)
  • Потяните еще 10000 строк и добавьте его в файл.
  • Когда выдостигнуть конца таблицы - файл буфера для пользователя.

Идите по кругу, пока не получите все это.Мне пришлось проделать эту работу по двум причинам:

  1. Время ожидания
  2. Ошибка нехватки памяти.

Недостатки этогоМетод заключается в том, что для получения данных требуется много HTTP-вызовов.Также в это время могут быть строки, которые изменились и т. Д. Это довольно «грязный» способ сделать это.Мне еще предстоит найти что-то, что работает лучше.Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...