Leitura 65k linhas trava PHP / MySQL

2

Estou desenvolvendo um aplicativo PHP que processa endereços IP. Eu estou trabalhando com tabelas mysql contendo até 4 bilhões de linhas.

Eu tenho um script que atualmente precisa buscar 65536 endereços desta tabela e a interface mysql < - > php falha em dar uma resposta via PHP ou mesmo via phpMyAdmin quando tento extrair essas linhas de 65K. Se usado na linha de comando, o mysql fornecerá as linhas 65K sem problemas em cerca de 0,2 s.

A tabela contendo os endereços IP tem 3 índices (1 exclusivo, 2 primário) que supostamente ajudam a ir mais rápido, mas eu simplesmente não consigo passar tendo o mysql dando um array associativo de volta ao PHP para continuar meu processamento de dados.

O servidor é uma máquina Xeon recente dedicada com cerca de 32 GB de memória (não sei as especificações exatas).

Alguma pista sobre o que pode estar acontecendo aqui?

Obrigado antecipadamente.

    
por BlackPage 25.06.2015 / 09:45

1 resposta

1

mysqli e PDO operam no modo buffer por padrão. Isso significa que suas consultas estão efetivamente sujeitas ao limite de memória do processo PHP.

De link :

[In buffered mode], query results are immediately transferred from the MySQL Server to PHP and are then kept in the memory of the PHP process. This allows additional operations like counting the number of rows, and moving (seeking) the current result pointer. It also allows issuing further queries on the same connection while working on the result set. The downside of the buffered mode is that larger result sets might require quite a lot memory.

Você deve aumentar o limite de memória dos processos PHP no seu php.ini , aumentando a configuração memory_limit ou pode dizer às consultas para usar o modo sem buffer :

Unbuffered MySQL queries execute the query and then return a resource while the data is still waiting on the MySQL server for being fetched. This uses less memory on the PHP-side, but can increase the load on the server.

Exemplo do Mysqli:

$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

Exemplo de PDO:

$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
    
por 25.06.2015 / 19:24