Pergunta

Ok, aqui está um para os profissionais:

Há alguns anos, tenho trabalhado na minha própria implementação PHP ORM/ActiveRecord que nomeei Porco.dbobject.

É vagamente baseado no 'Make Your Own Site com Rails em 5 minutos de filme que todos vimos há alguns anos. Você pode fazer coisas como:

$clients = dbObject::Search("Client", array("ID > 500")); 

ou

$client = new Client(218); // fetch row with id 218 from client table

ou

$projects = $client->Find('Project');

Isso buscará uma ou mais linhas do banco de dados, envolverá -as em um dbobject e as devolverá em uma matriz ou retornará falsa de não há resultados.

Tudo isso tem funcionado perfeitamente em dezenas de sites e back -ends, mas agora meu colega está usando -o para criar um enorme logparser e aqui inicia os problemas de uso da memória.

As consultas que ele administra podem retornar mais de 20.000 linhas, talvez até mais, o que é claro que não é uma coisa muito boa para envolver um invólucro de objetos de uma só vez e retornar como uma única matriz.

A solução óbvia seria devolver um objeto que implementa o Iterador interface em vez de uma matriz. Ele não deve buscar instantaneamente todos os registros do ResultSet, mas basta manter o recurso de resultado para a consulta de banco de dados gerada e usar mysql_fetch_* internamente quando você atravessa o objeto como se fosse uma matriz.

Agora chegamos à minha verdadeira pergunta: posso, sem problemas, apenas fazer isso? Os bancos de dados podem lidar com vários resultados abertos e misturá -los e mantê -los na memória por um tempo?

Por exemplo, busque 20 objetos, entre eles, deixe cada um desses 20 busca 5 outros, que, por sua vez, também buscar 3 outros. Isso criaria um loop onde várias alças de resultado diferentes serão mantidas na memória.

Sei que não posso serializar em serializar um desses objetos, mas poderei implementar isso sem problemas no PHP5 ou as interfaces de banco de dados me darão problemas?

Foi útil?

Solução

Depende de qual banco de dados você está usando e da sua configuração de banco de dados.

Para o MySQL, você precisa usar consultas em buffer. Na PDO, você define assim:

$myPdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

Isso significa que todos os dados serão enviados ao cliente (não o mesmo que buscar tudo isso no PHP).

A outra alternativa (provavelmente pior) é abrir uma nova conexão de banco de dados sempre que você detectar uma consulta sendo executada com um conjunto de resultados ainda aberto.

O normal mysql_query() usa uma consulta em buffer, para que funcione com vários conjuntos de resultados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top