Pregunta

Estoy consultas de ejecución contra un Oracle 10g con JDBC (utilizando los últimos controladores y UCP como origen de datos) con el fin de recuperar CLOBs (prom. 20k caracteres). Sin embargo, el rendimiento parece ser bastante malo: la recuperación de lote de 100 LOB toma 4s en promedio. La operación también es ni de E / S de la CPU, ni tampoco a la red con destino a juzgar por mis observaciones.

Mi configuración de la prueba es el siguiente:

PoolDataSource dataSource = PoolDataSourceFactory.getPoolDataSource();
dataSource.setConnectionFactoryClassName("...");
dataSource.setConnectionPoolName("...");
dataSource.setURL("...");
dataSource.setUser("...");
dataSource.setPassword("...");

dataSource.setConnectionProperty("defaultRowPrefetch", "1000");
dataSource.setConnectionProperty("defaultLobPrefetchSize", "500000");

final LobHandler handler = new OracleLobHandler();
JdbcTemplate j = new JdbcTemplate(dataSource);

j.query("SELECT bigClob FROM ...",

        new RowCallbackHandler() {

            public void processRow(final ResultSet rs) throws SQLException {

                String result = handler.getClobAsString(rs, "bigClob");

            }

        });

}

he experimentado con los tamaños fetch pero fue en vano. ¿Estoy haciendo algo mal? ¿Hay una manera de acelerar la recuperación CLOB cuando se utiliza JDBC?

¿Fue útil?

Solución 4

Gracias por todas las sugerencias útiles. A pesar de estar marcado como respuesta al problema de mi respuesta es que no parece haber ninguna buena solución. He intentado utilizar declaraciones paralelas, diferentes características de almacenamiento, temperatura preclasificado. mesas y otras cosas. La operación no parece estar ligado a ninguna característica visible a través de las huellas o explicar los planes. Incluso paralelismo de consultas parece ser peligrosa cuando se trata de CLOBs.

Sin duda no habría mejores opciones para hacer frente con grandes CLOBs (especialmente de compresión) en un entorno 11g pero atm. Estoy atascado con 10 g.

He optado ahora para una ida y vuelta adicional a la base de datos en la que voy a preprocesar los CLOBs en un tamaño optimizado binarios sin formato. En las implementaciones anteriores esto siempre ha sido una opción muy rápido y es probable que valdrá la pena la molestia de mantener una línea computado caché. La memoria caché será inválido y actualización a través de un proceso persistente y AQ hasta que alguien se le ocurre una idea mejor.

Otros consejos

Mi experiencia pasada de la utilización de los datos de tipo LOB Oracle para almacenar grandes cantidades de datos no ha sido buena. Está bien cuando está bajo 4k ya que almacenarlo localmente como VARCHAR2. Una vez que se ha terminado 4k, se empiezan a ver disminuir el rendimiento. Tal vez, las cosas pueden haber mejorado desde la última vez que probé hace un par de años, pero aquí están las cosas que encontré en el pasado para su información:

A medida que los clientes necesitan para obtener los LOB a través del servidor Oracle, puede considerar la siguiente situación interesante.

  • LOB de datos competirá limitada SGA caché con otro tipo de datos si Oracle decidir almacenar en caché. Como los datos son CLOB en general grande, por lo que puede empujar a otra datos
  • Los datos LOB consiguen pobres de lectura de disco si Oracle no decide almacenar en caché, y transmitir los datos al cliente.
  • fragmentación es probablemente algo que no ha encontrado todavía. Va a ver si sus aplicaciones borran globos, y Oracle intenta reutilizar la pelota alta. No sé si el soporte para Oracle en línea desfragmentación del disco de vaselina (que tienen para los índices, pero se necesita mucho tiempo cuando intentamos anterior).

Usted ha mencionado 4s para 100 globos de 20k promedio, por lo que es de 40 ms por globos. Recuerde que cada globo tiene que tener a recuperar a través de la pelota alta localizador separado (no está en el conjunto de resultados por defecto). Esa es una de ida y vuelta adicional por cada pelota alta, supongo (no estoy 100% seguro de esto, ya que fue hace un tiempo) Si ese es el caso, supongo que habrá al menos 5 ms de tiempo extra por viaje redondo con el fin de serie , ¿derecho? Si es así, su rendimiento ya está limitado por primera pelota alta secuencial obtiene. Usted debe ser capaz de verificar esto mediante el seguimiento del tiempo empleado en la ejecución de SQL vs ir a buscar el contenido vaselina. O puede verificar esto mediante la exclusión de la columna de la pelota alta como se sugiere en la respuesta anterior en el cargo, que debe decirle si está relacionado vaselina.

Buena suerte

  

El tamaño total del conjunto de resultados es en los diez miles - medido en el lapso de toda la recuperación de los costes iniciales

¿Hay una orden en la consulta? 10K filas es mucho si tiene que ser ordenados.

Además, la recuperación de la PK no es una prueba justo frente a la recuperación de todo el CLOB. Oracle almacena las filas de la tabla con probablemente muchos en un bloque, pero cada uno de los CLOBs (si son> 4K) será almacenado fuera de la línea, cada uno en una serie de bloques. El escaneo de la lista de PK es, por tanto, va a ser rápido. Además, es probable que haya un índice en el PK, por lo que Oracle solo puede explorar rápidamente los bloques de índices y ni siquiera acceder a la tabla.

4 segundos parece un poco alto, pero es de 2 MB que debe ser posible leer del disco y se transporta a través de la red el programa Java. La red podría ser un problema. Si realiza una traza de SQL de la sesión que se va a apuntar exactamente a dónde se gasta el tiempo (las lecturas del disco o de la red).

Yo tenía un problema similar y encontré el JDBC Lobs hacer una llamada a la red cuando el accessin globos.

A partir de 11,2 g de Oracle controlador JDBC se puede utilizar una captura previa. Esto aceleró el acceso de 10 veces ...

statement1.setFetchSize(1000);
if (statement1 instanceof OracleStatement) {
    ((OracleStatement) statement1).setLobPrefetchSize(250000);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top