Optimizar cursores Java-Oracle

A menudo muchos programadores necesitan por algunas circunstancias leer gran cantidad de registros desde una base de datos Oracle o enviar una gran cantidad de registros. Lo que genera un grave problema de desempeño, el tiempo en que a Java le toma leer millones de registros o enviar millones de insert es muy tardado.

Lo mas recomendable en estos casos es utilizar procedimientos almacenados dentro de la base de datos, pero si esto no es posible, hay un pequeño consejo para mejorar notablemente el rendimiento, en mi experiencia, reduce a mas de la mitad el tiempo de lectura o escritura en un cursor abierto en Java.

Para lectura:

...
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
...
PreparedStatement pstmt = conn.prepareStatement(
	"SELECT ... FROM ...");
ResultSet rs = pstmt.executeQuery();
rs.setFetchSize(1024);
while (rs.next()) {
    ...
}
rs.close();
...

Para escritura:

...
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
...
PreparedStatement pstmt = conn.prepareStatement(
				"INSERT INTO ... VALUES (?)");
((OraclePreparedStatement)pstmt).setExecuteBatch(1024);
...
while ((line=buffer.readLine()) != null) {
    pstmt.setString(1, line);
    pstmt.executeUpdate();
}
...

El funcionamiento es solo procesamiento por bloques, ya que el Driver de Oracle (ojdbc14.jar o otro dependiendo de la versión) almacena 1024 envíos en memoria y los envía en un solo paquete cuando se completa el numero de instrucciones o se finaliza (pstmt.close()), aunque he hecho pruebas de incrementar el tamaño de instrucciones a más de 1024 (el numero no es en bytes sino en numero de instrucciones) ya no impacta en un mejor desempeño.

Existe un problema, en el caso de los inserts, ya que si la aplicación es abortada de forma repentina, las instrucciones acumuladas en memoria no son enviadas. Por lo que puede existir problemas si se llevan controles de registros insertados, ya que al ejecutar pstmt.executeUpdate(); no son enviadas inmediatamente.

Bueno espero y les ayude, como les dije, la mejora de rendimiento es bastante notable.
🙂

Anuncios

3 pensamientos en “Optimizar cursores Java-Oracle

  1. En “ojdbc14.jar o otro dependiendo de la versión” aplica mejor “ojdbc14.jar u otro dependiendo de la versión”. Buen artículo.

    Saludos.

    Orlando.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s