PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Qual è il modo più veloce per recuperare dati sequenziali dal database?

SELECT * FROM table ORDER BY column

Non c'è motivo di risucchiare l'intera tabella nella RAM. Basta aprire un cursore e iniziare a leggere. Puoi giocare a giochi con dimensioni di recupero e altro, ma il DB manterrà felicemente il suo posto mentre elabori le tue righe.

Appendice:

Ok, se stai usando Java, allora ho una buona idea di quale sia il tuo problema.

Innanzitutto, semplicemente usando Java, stai usando un cursore. Questo è fondamentalmente ciò che un ResultSet è in Java. Alcuni ResultSet sono più flessibili di altri, ma il 99% di essi sono semplici, inoltra solo ResultSet su cui chiami "next" per ottenere ogni riga.

Ora per quanto riguarda il tuo problema.

Il problema riguarda in particolare il driver JDBC di Postgres. Non so perché lo fanno, forse è una specifica, forse è qualcos'altro, ma a prescindere, Postgres ha la curiosa caratteristica che se la tua connessione ha autoCommit impostato su true, Postgres decide di risucchiare l'intero set di risultati su entrambi eseguire il metodo o il primo metodo successivo. Non è molto importante dove, solo che se hai un miliardo di righe, ottieni una bella eccezione OOM. Non utile.

Questo può facilmente essere esattamente ciò che stai vedendo e apprezzo il modo in cui può essere piuttosto frustrante e confuso.

La maggior parte delle connessioni è impostata su autoCommit =true. Invece, imposta semplicemente autoCommit su false.

Connection con = ...get Connection...
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("SELECT * FROM table ORDER BY columm");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
    String col1 = rs.getString(1);
    ...and away you go here...
}
rs.close();
ps.close();
con.close();

Si noti la netta mancanza di gestione delle eccezioni, lasciata come esercizio per il lettore.

Se desideri un maggiore controllo su quante righe vengono recuperate alla volta in memoria, puoi utilizzare:

ps.setFetchSize(numberOfRowsToFetch);

Giocare con questo potrebbe migliorare le tue prestazioni.

Assicurati di avere un indice appropriato sulla colonna che usi in ORDER BY se ti interessa il sequenziamento.