2013-03-22 5 views
5

У меня есть самая странная проблема с PHP PDO, и я надеюсь, что вы, ребята, можете разобраться со мной.PHP-запрос PDO не выполняется, когда LIMIT слишком высок?

Если я установил $checkLimit на 50000, запрос будет работать нормально. Однако, если установить его на что-либо выше 50к, он не возвращает никаких результатов - и он не отбрасывает никаких сообщений об ошибках либо (я уже повернул их на использовании $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING)

$sql = " 
    SELECT d_domain_name AS domainName, d_domain_id AS domainID 
    FROM domains 
    ORDER BY d_domain_name_length ASC, d_domain_name ASC 
    LIMIT :checkLimit 
"; 
$stmt = $db->prepare($sql); 
$stmt->bindValue(':checkLimit', intval($checkLimit), PDO::PARAM_INT); 
$stmt->execute(); 
$results = $stmt->fetchAll(); 
foreach ($results as $result) { 
// 50k moments of magic 
} 

Если я бегу. запрос за пределами PHP, он работает с любым пределом (даже 500 тыс., занимает около 3 минут).

Я попытался сменить $results = $stmt->fetchAll() на while ($result = $stmt->fetch()) {}, чтобы попытаться сохранить память, но это ничего не сделало, к сожалению

Может ли кто-нибудь сказать мне, что я делаю неправильно здесь? Что мне не хватает? Почему я не могу пройти через 50 000?

+0

Учитывайте, что значения 'int' не бесконечны, возможно, вы получили превышение лимита. – fedorqui

+2

Это не так? Не оставляй нас в напряжении! –

+0

@fedorqui: 50 000 подходят ОЧЕНЬ удобно в 32-битный PHP int –

ответ

4

Ссылка: http://php.net/manual/en/mysqlinfo.concepts.buffering.php

PDO использует "буферизованный запрос" по умолчанию.

Это означает, что результаты запроса немедленно переносятся с сервера MySQL на PHP, а затем хранятся в памяти процесса PHP. .... Недостатком буферизованного режима является то, что для большего размера наборов может потребоваться довольно много памяти. ....

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

50k - большой результирующий набор. Не могли бы вы попытаться использовать . Пусть pdo использует небуферизованный режим и выборки по одной строке за раз? Это пример, скопированный из ссылки. Вторая строка устанавливает небуферизованный режим.

<?php 
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); 
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); 

$uresult = $pdo->query("SELECT Name FROM City"); 
if ($uresult) { 
    while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { 
     echo $row['Name'] . PHP_EOL; 
    } 
} 
?> 
+0

приятный, это интересно – Sebas

+0

Он отлично работает - за исключением того, что я не могу выполнять новые запросы внутри запроса; 'Невозможно выполнить запросы, в то время как другие небуферизованные запросы активны. Рассмотрим использование PDOStatement :: fetchAll().Альтернативно, если ваш код будет работать только с mysql, вы можете включить буферизацию запросов, установив атрибут PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY. ' –

+0

Не могли бы вы попробовать открыть другое соединение pdo с той же базой данных для других буферизованных запросов? –

Смежные вопросы