Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Streaming de grandes conjuntos de resultados com MySQL


Apenas definir o tamanho da busca não é a abordagem correta. O javadoc de Statement#setFetchSize() já afirma o seguinte:

Dá ao driver JDBC uma dica quanto ao número de linhas que devem ser buscadas no banco de dados

O driver é realmente livre para aplicar ou ignorar a dica. Alguns drivers o ignoram, alguns drivers o aplicam diretamente, alguns drivers precisam de mais parâmetros. O driver MySQL JDBC se enquadra na última categoria. Se você verificar o driver MySQL JDBC documentação , você verá as seguintes informações (role cerca de 2/3 para baixo até o cabeçalho ResultSet ):

Para habilitar essa funcionalidade, você precisa criar uma instância de Statement da seguinte maneira:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

Por favor, leia todo seção do documento, ele descreve as advertências dessa abordagem também. Aqui está uma citação relevante:

Existem algumas ressalvas com essa abordagem. Você terá que ler todas as linhas no conjunto de resultados (ou fechá-lo) antes de poder emitir qualquer outra consulta na conexão, ou uma exceção será lançada.

(...)

Se a instrução estiver dentro do escopo de uma transação, os bloqueios serão liberados quando a transação for concluída (o que implica que a instrução precisa ser concluída primeiro). Como na maioria dos outros bancos de dados, as instruções não são concluídas até que todos os resultados pendentes na instrução sejam lidos ou o conjunto de resultados ativo para a instrução seja fechado.

Se isso não corrigir o OutOfMemoryError (não Exception ), é provável que você esteja armazenando todos os dados na memória do Java em vez de processá-los imediatamente assim que os dados chegarem. Isso exigiria mais alterações em seu código, talvez uma reescrita completa. Respondi a uma pergunta semelhante antes aqui .