Mysql
 sql >> Database >  >> RDS >> Mysql

Streaming di grandi set di risultati con MySQL

Solo l'impostazione della dimensione di recupero non è l'approccio corretto. Il javadoc di Statement#setFetchSize() afferma già quanto segue:

Dà un suggerimento al driver JDBC per quanto riguarda il numero di righe che devono essere recuperate dal database

Il conducente è effettivamente libero di applicare o ignorare il suggerimento. Alcuni driver lo ignorano, alcuni lo applicano direttamente, altri richiedono più parametri. Il driver MySQL JDBC rientra nell'ultima categoria. Se controlli il driver MySQL JDBC documentazione , vedrai le seguenti informazioni (scorri di circa 2/3 verso il basso fino all'intestazione ResultSet ):

Per abilitare questa funzionalità, devi creare un'istanza di Statement nel modo seguente:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);

Si prega di leggere l'intero sezione del documento, descrive anche le avvertenze di questo approccio. Ecco una citazione pertinente:

Ci sono alcuni avvertimenti con questo approccio. Dovrai leggere tutte le righe nel set di risultati (o chiuderlo) prima di poter eseguire altre query sulla connessione, altrimenti verrà generata un'eccezione.

(...)

Se l'istruzione rientra nell'ambito di una transazione, i blocchi vengono rilasciati al completamento della transazione (il che implica che l'istruzione deve prima essere completata). Come con la maggior parte degli altri database, le istruzioni non sono complete finché non vengono letti tutti i risultati in sospeso sull'istruzione o il set di risultati attivo per l'istruzione non viene chiuso.

Se ciò non risolve il OutOfMemoryError (non Exception ), è probabile che tu stia archiviando tutti i dati nella memoria di Java invece di elaborarli immediatamente non appena i dati arrivano. Ciò richiederebbe più modifiche al codice, forse una riscrittura completa. Ho risposto a una domanda simile prima qui .