Java JDBC ignora setFetchSize?

Sto usando il seguente codice

st = connection.createStatement( ResultSet.CONCUR_READ_ONLY, ResultSet.FETCH_FORWARD, ResultSet.TYPE_FORWARD_ONLY ); st.setFetchSize(1000); System.out.println("start query "); rs = st.executeQuery(queryString); System.out.println("done query"); 

La query restituisce un sacco di (800k) righe e impiega molto tempo (~ 2m) tra la stampa “start query” e “done query”. Quando inserisco manualmente un “limite 10000” nella mia query non c’è tempo tra “start” e “done”. Elaborare i risultati richiede tempo quindi immagino che nel complesso sia più veloce se recupera solo le righe da 1k dal database, le elabora e quando sta esaurendo le righe ne può ottenere di nuove in background.

Il ResultsSet.CONCUR_READ_ONLY ecc. Dove la mia ultima ipotesi; mi sto perdendo qualcosa?

(è un server 8.3 postgresql)

Prova a distriggersre l’auto-commit:

 // make sure autocommit is off connection.setAutoCommit(false); st = connection.createStatement(); st.setFetchSize(1000); System.out.println("start query "); rs = st.executeQuery(queryString); System.out.println("done query"); 

Riferimento

Le due domande fanno cose completamente diverse.

L’uso della clausola LIMIT limita la dimensione del set di risultati a 10000, mentre l’impostazione della dimensione di recupero non lo fa, fornisce invece un suggerimento all’autista che dice quante righe recuperare in un momento durante l’iterazione attraverso il set di risultati – che include tutti gli 800k filari.

Quindi, quando si utilizza setFetchSize , il database crea il set di risultati completo, ecco perché ci vuole così tanto tempo.

Modifica per chiarezza: l’ impostazione della dimensione del recupero non ha effetto se non si scorre il risultato (vedere il commento di Jon), ma la creazione di un risultato molto più piccolo impostato con LIMIT fa una grande differenza.

Questo dipenderà dal tuo autista. Dai documenti:

Fornisce al driver JDBC un suggerimento sul numero di righe che dovrebbero essere recuperate dal database quando sono necessarie più righe. Il numero di righe specificato riguarda solo i set di risultati creati utilizzando questa istruzione. Se il valore specificato è zero, il suggerimento viene ignorato. Il valore di default è zero.

Nota che dice “un suggerimento” – direi che un driver può ignorare il suggerimento se lo vuole davvero … e sembra che sia quello che sta succedendo.

Ho notato che il tuo uso dell’API è diverso da quello express da Javadoc:

Prova a passare i parametri in questo ordine

  ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.FETCH_FORWARD