Actualmente estoy enfrentando un problema por el cual una consulta SQL específica tarda unos 30 segundos en emitirse desde mi aplicación Java pero < 1 segundo en un SQL-client (SQL Developer).Problemas de rendimiento con JDBC
En la pregunta,
Slow query in Java by JDBC but not in other systems (TOAD), se sugiere que el uso de un PreparedStatement con destino a las variables Java podría realizar la consulta ejecutar mucho más lento que en el SQL-cliente (SAPO en ese caso), ya que Oracle se está confundido acerca de qué índices para usar. ¿Podría ser esto un problema con un PreparedStatement sin parámetros también?
¿Cuál podría ser el problema?
La consulta se ve algo así como
select
sum(col1),
sum(col2),
max(select ...)
from view_
where time_id = get_time_id(to_date('2010-10-10','yyyy-mm-dd'))
donde view_ es una vista compleja que contiene agregados de mesas y otros puntos de vista complejos. La consulta se ejecuta como un PreparedStatement pero sin ningún parámetro. No parece hacer una diferencia si usamos una declaración preparada o simplemente declaraciones simples.
Dado que el plan de ejecución es bastante grande que no se puede publicar todo si aquí, pero la diferencia relevante parece ser:
UNION-ALL TABLE ACCESS FULL GVC_WH.PLAYER_FACT_DAILY TABLE 37 6717151 596,934.317 19940 240 7621178231 19502
UNION-ALL TABLE ACCESS BY INDEX ROWID GVC_WH.PLAYER_FACT_DAILY TABLE 38 2657 236.120 2429 30 20544658 2428 INDEX RANGE SCAN GVC_WH.PK_AGG_PLAYER INDEX (UNIQUE) 37 2657 16 1 638743 16
Cuando el primer fragmento es de cuando se ejecuta con el JDBC Thin Client y el segundo desde que se ejecuta dentro de SQL Developer. No está recogiendo el índice correcto cuando se ejecuta como una declaración (no importa si uso una declaración preparada o no) con el Thin Client de JDBC. La diferencia de tiempo i 30 segundos para el primero y 0.5 segundos para el segundo.
¿Podría ser que usar la función get_time_id prohíbe el uso del índice cuando se usa a través de JDBC, aunque no funcione en la columna y aunque parezca estar funcionando en SQL Developer?
¿Puede obtener y publicar los planes de consulta para los dos casos?Y para mayor claridad, ¿eres coherente sobre cómo estás midiendo el rendimiento? Es algo común medir accidentalmente el momento en que SQL Developer devuelve la primera fila frente al momento en que su código Java recupera la última fila, que puede ser sustancialmente diferente. –
Comenzaría mirando el plan de ejecución (mediante dbms_xplan.display cursor) generado por cada método (TOAD vs. Java). Eso debería decirle si la base de datos trata las consultas de manera diferente. Si es así, preste mucha atención a la sección de predicados, ya que es probable que le proporcione algunas pistas sobre por qué (por ejemplo, la conversión de tipo de datos implícita se produce a partir de la versión de Java y hace que Oracle no pueda usar un índice) – Craig
Véase también http://stackoverflow.com/questions/3976184/oracle-query-ora-01652-unable-to-extend-temp-segment-but-only-in-some-versions – symcbean