2009-02-23 14 views
6

Mam poważne problemy z funkcjami PHP Data Object. Próbuję przechodzić przez znaczący zestaw wyników (~ 60k wierszy, ~ 1gig) za pomocą buforowanego zapytania, aby uniknąć pobierania całego zestawu.Zapytanie buforowane PHP PDO

Niezależnie od tego, co robię, skrypt po prostu zawiesza się na PDO :: query() - wygląda na to, że zapytanie działa w trybie niebuforowanym (dlaczego indziej zmiana rozmiaru zestawu wyników 'rozwiązałaby problem?). Oto mój kod do odtworzenia problemu:

Gdybym ograniczyć kwerendy z jakiejś rozsądnej liczby, to działa dobrze:

$rQuery = $Database->query('SELECT id FROM mytable LIMIT 10'); 

Próbowałem grać z PDO :: MYSQL_ATTR_MAX_BUFFER_SIZE i korzystania z PDO :: prepare() i PDO :: execute() jak również (choć nie ma parametrów w powyższym zapytaniu), oba bez skutku. Każda pomoc będzie doceniona.

Odpowiedz

8

Jeśli dobrze rozumiem to, buforowane zapytania wiążą się z informacją PHP, że należy poczekać na cały zestaw wyników przed rozpoczęciem przetwarzania. Przed PDO było to domyślne i musiałeś zadzwonić pod numer mysql_unbuffered_query, jeśli chcesz natychmiast zająć się wynikami.

Dlaczego nie jest to wyjaśnione na stronie sterownika MySQL PDO, nie wiem.

+0

Wow porządku jestem idiotą . Nie wiem, co sprawiło mi przeciwne wrażenie. – Stewart

+0

Pod względem technicznym "buforowana" kwerenda oznacza, że ​​biblioteka klienta MySQL wyciąga cały zestaw wyników ze strumienia TCP, zanim przekaże go z powrotem. – staticsan

+0

Hmm, myślałem, że instrukcja obejmuje różnicę między buforowanym/niebuforowanym (styl mysql) i fetch/fetchAll (styl PDO), ale patrząc ponownie nie. Jeśli chcesz uzyskać więcej informacji dodatkowych, możesz znaleźć następujące przydatne informacje: http://netevil.org/blog/2008/06/slides-pdo –

1

Można spróbować podzielić go na kawałki, które nie są na tyle duże, aby powodować problemy:

<?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 
     ) 
     ); 
?> 

... masz pomysł, w każdym razie.

-1

Albo można spróbować funkcji mysql zamiast:

while ($row = mysql_fetch_row($query)) { 
... 
} 

Które z pewnością będą szybsze, ponieważ oświadczenie foreach sprawia wrażenie używać fetchAll() zamiast fetch() każdy wiersz

+1

funkcje mysql_ są przestarzałe i nie powinny być używane – vvondra