У меня возникли серьезные проблемы с функциями объекта данных PHP. Я пытаюсь пройти через значительный набор результатов (~ 60k строк, ~ 1gig), используя буферный запрос, чтобы избежать выборки всего набора.
Независимо от того, что я делаю, сценарий просто зависает на PDO :: query () – кажется, что запрос работает небуферизованным (почему еще изменилось бы изменение размера набора результатов?). Вот мой код, чтобы воспроизвести проблему:
<?php $Database = new PDO( 'mysql:host=localhost;port=3306;dbname=mydatabase', 'root', '', array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true ) ); $rQuery = $Database->query('SELECT id FROM mytable'); // This is never reached because the result set is too large echo 'Made it through.'; foreach($rQuery as $aRow) { print_r($aRow); } ?>
Если я ограничу запрос некоторым разумным числом, он отлично работает:
$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10');
Я попытался сыграть с PDO :: MYSQL_ATTR_MAX_BUFFER_SIZE и использовать PDO :: prepare () и PDO :: execute () (хотя в вышеприведенном запросе нет параметров), и это не помогло. Любая помощь будет оценена по достоинству.
Если я понимаю это правильно, буферизованные запросы включают в себя указание PHP, что вы хотите дождаться всего набора результатов перед началом обработки. До PDO это было по умолчанию, и вам нужно было вызвать mysql_unbuffered_query
если вы хотите немедленно mysql_unbuffered_query
результаты.
Почему это не объясняется на странице драйвера PDO MySQL, я не знаю.
Вы можете попытаться разбить его на куски, которые недостаточно велики, чтобы вызвать проблемы:
<?php $id = 0; $rQuery = $Database->query('SELECT id FROM mytable ORDER BY id ASC LIMIT 100'); do { stuff($rQuery); $id += 100; } while ( $rQuery = $Database->query( 'SELECT id FROM mytable ORDER BY id ASC LIMIT 100 OFFSET '.$id ) ); ?>
Во всяком случае, у вас есть идея.
Или, может быть, вы можете попробовать mysql-функции:
while ($row = mysql_fetch_row($query)) { ... }
Который определенно будет быстрее, поскольку этот оператор foreach производит впечатление на использование fetchAll()
вместо fetch()
каждой строки