PHP7 PDO ext читает весь набор результатов в память?
Я заметил, что с тех пор, как я обновился до PHP7, некоторые операторы SQL больше не работают и, вместо этого, исчерпали память.
У меня есть этот код:
$query = Yii::$app->db->createCommand('select * from tbl_title')->query();
while ($row = $reader->read()) {
var_dump($row);
exit();
}
И абстракция базы данных Yii2 - это очень тонкий слой над PDO и не делает ничего лишнего. query()
ничего не делает, кроме добавления строки в файл журнала (Yii2) для профилирования и reader->read()
просто вызывает функцию потока PDO fetch()
.
Но у него заканчивается память с указанием размера (пробела) моей таблицы, т.е. попытки выделить 385 МБ памяти процесса:
Разрешенный размер памяти 134217728 байт исчерпан (пытался выделить 385883840 байт)
Как гаечный ключ, если я использую запрос, чей результирующий набор полностью соответствует пределу 128 МБ процесса PHP.
Итак, изменился ли PHP7 и я могу его изменить?
Ответы
Ответ 1
Он не связан напрямую с PHP7. Проблема связана с новым драйвером mysqlnd, поэтому вы можете столкнуться с той же проблемой даже с PHP 5.x. Это на самом деле ошибка, потому что еще до того, как память все еще была выделена, но это не учитывалось в memory_limit.
Чтобы избежать проблемы с памятью, вы должны использовать небуферизованные запросы для больших наборов результатов.
Итак, для запроса, который ожидает большой набор данных, установите правильную настройку следующим образом:
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
Для дальнейшего чтения я получил достойное объяснение в своем уроке по PDO, благодаря Никичу, чья критическая обратная связь была неоценимой.