Задать вопрос

'Allowed memory size of 134217728 bytes exhausted' Почему это происходит с PDO, при выборке всего 27k записей?

Пытаюсь выбрать 27к строк (нужно сделать отчет), но выкидывает с ошибкой "Allowed memory size of 134217728 bytes exhausted' . Проблему я обошел и не выбираю всё сразу, а делаю это построчно. Был бы благодарен если бы рассказали почему при выборке таблицы приблизительным размером 18 MiB, PDO падает хотя ограничение доступной памяти установлено в 128 MiB.
(php 5.6 если это важно)

Померил количество поглощаемой памяти другим способом и оно оказалось огромно 174660600 bytes при 38520 записей (взял побольше чтобы лучше видеть разницу). Получается что на 1 стоку приходится ~ 4534 байта. Ну не слишком ли это для
id int(11)
f2 tinyint(1)
f3 int(11)
f4 datetime
f5 datetime
f6 varchar(255) utf8mb4_unicode_ci
f7 varchar(255) utf8mb4_unicode_ci
f8 varchar(255) utf8mb4_unicode_ci
f9 varchar(255) utf8mb4_unicode_ci
f10 int(11)
f11 int(11)
f12 text utf8mb4_unicode_ci
f13 varchar(36)
Если только PDO не выделяет по факту, а чисто по декларации поля ... тогда там наберется. Но это очень странно... (мягко говоря)
  • Вопрос задан
  • 1151 просмотр
Подписаться 3 Оценить 4 комментария
Решения вопроса 1
FanatPHP
@FanatPHP
Чебуратор тега РНР
Единственная независящая от программиста причина, по которой PDO будет жрать память, это буферизованные по умолчанию запросы. поэтому если перед выполнением запроса написать
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, FALSE);

То ошибка исчезнет.
Остальные рекомендации настолько очевидны, что я постеснялся их писать сначала.

1. При выборке большого объема данных fetchAll() использовать не рекомендуется.
2. Если все же хотим использовать, то надо убрать двойное заполнение массива
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

Все остальные претензии по памяти предъявлять РНР и собственному коду.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы