2009-02-23 19 views
6

Tengo algunos problemas graves con las funciones de objetos de datos de PHP. Estoy intentando recorrer un conjunto de resultados considerable (~ 60k filas, ~ 1gig) usando una consulta almacenada para evitar recuperar todo el conjunto.Problema con la consulta de PHP PDO

No importa lo que haga, la secuencia de comandos simplemente cuelga en PDO :: query() - parece que la consulta se está ejecutando sin búfer (¿por qué el cambio en el tamaño del conjunto de resultados 'solucionó' el problema?). Aquí está mi código para reproducir el problema:

Si puedo limitar la consulta con un número razonable, que trabaja muy bien:

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

He intentado jugar con PDO :: MYSQL_ATTR_MAX_BUFFER_SIZE y el uso de la DOP :: prepare() y PDO :: execute() también (aunque no hay parámetros en la consulta anterior), ambos en vano. Cualquier ayuda sería apreciada.

Respuesta

8

Si entiendo esto bien, las consultas en el búfer implican decirle a PHP que desea esperar el conjunto de resultados completo antes de comenzar el procesamiento. Antes de PDO, este era el valor predeterminado y tenía que llamar al mysql_unbuffered_query si deseaba tratar los resultados de inmediato.

Por qué esto no se explica en la página del controlador de MySQL de PDO, no lo sé.

+0

Wow bien que soy un idiota . No sé lo que me dio la impresión contraria. – Stewart

+0

Técnicamente, una consulta "almacenada en el búfer" significa que la biblioteca del cliente MySQL extrae todo el conjunto de resultados de la transmisión TCP antes de devolvérselo. – staticsan

+0

Hmm, pensé que el manual cubría la diferencia entre el búfer/sin búfer (estilo mysql) y fetch/fetchAll (estilo PDO), pero mirando de nuevo no es así. Si desea obtener más información de antecedentes, puede encontrar la siguiente información útil: http://netevil.org/blog/2008/06/slides-pdo –

1

Se podría tratar de dividirlo en trozos que no son lo suficientemente grandes como para causar problemas:

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

... se entiende la idea, de todos modos.

-1

O tal vez usted podría intentar funciones de MySQL en su lugar:

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

que sin duda será más rápido, ya que la instrucción foreach hace una impresión a utilizar en lugar fetchAll()fetch() cada fila

+1

Las funciones de mysql_ están en desuso y no deben usarse – vvondra