La versión corta es llamar a stmt.setFetchSize(50);
y conn.setAutoCommit(false);
para evitar leer todo el ResultSet
en la memoria.
Esto es lo que dicen los documentos:
Obtener resultados basados en un cursor
De forma predeterminada, el controlador recopila todos los resultados de la consulta a la vez. Esto puede ser un inconveniente para grandes conjuntos de datos, por lo que el controlador JDBC proporciona un medio para basar un ResultSet en un cursor de base de datos y obtener solo una pequeña cantidad de filas.
Una pequeña cantidad de filas se almacenan en caché en el lado del cliente de la conexión y, cuando se agotan, el siguiente bloque de filas se recupera reposicionando el cursor.
Nota:
-
Los ResultSets basados en cursores no se pueden utilizar en todas las situaciones. Hay una serie de restricciones que harán que el controlador retroceda silenciosamente para obtener todo el ResultSet a la vez.
-
La conexión al servidor debe estar utilizando el protocolo V3. Este es el valor predeterminado para (y solo es compatible con) las versiones de servidor 7.4 y posteriores.-
-
La conexión no debe estar en modo de confirmación automática. El backend cierra los cursores al final de las transacciones, por lo que en el modo de confirmación automática, el backend habrá cerrado el cursor antes de que se pueda obtener algo de él.-
-
La declaración debe crearse con un tipo de conjunto de resultados de ResultSet.TYPE_FORWARD_ONLY. Este es el valor predeterminado, por lo que no será necesario volver a escribir el código para aprovechar esto, pero también significa que no puede desplazarse hacia atrás o saltar de otro modo en el ResultSet.-
-
La consulta proporcionada debe ser una declaración única, no varias declaraciones encadenadas con punto y coma.
Cambiar el código al modo de cursor es tan simple como establecer el tamaño de recuperación de la instrucción en el tamaño adecuado. Establecer el tamaño de obtención de nuevo en 0 hará que todas las filas se almacenen en caché (el comportamiento predeterminado).
// make sure autocommit is off
conn.setAutoCommit(false);
Statement st = conn.createStatement();
// Turn use of the cursor on.
st.setFetchSize(50);
ResultSet rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next()) {
System.out.print("a row was returned.");
}
rs.close();
// Turn the cursor off.
st.setFetchSize(0);
rs = st.executeQuery("SELECT * FROM mytable");
while (rs.next()) {
System.out.print("many rows were returned.");
}
rs.close();
// Close the statement.
st.close();