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, благодаря Никичу, чья критическая обратная связь была неоценимой.