oracledriver - oracle jdbc 8
Problemas de rendimiento con JDBC (3)
Actualmente estoy enfrentando un problema en el que una consulta SQL específica tarda unos 30 segundos en emitirse desde mi aplicación Java, pero <1 segundo en un cliente SQL (SQL Developer).
En la pregunta,
Consulta lenta en Java por JDBC pero no en otros sistemas (TOAD) , se sugiere que el uso de un PreparedStatement vinculado a las variables java podría hacer que la consulta se ejecute mucho más lento que en el SQL-client (TOAD en ese caso) porque Oracle se confunde sobre qué índices usar ¿Podría ser esto un problema con un PreparedStatement sin parámetros también?
¿Qué 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 agregaciones de tablas y otras vistas complejas. 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, no puedo publicar todo si está 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
De dónde es el primer fragmento al ejecutarlo con el Thin Client de JDBC y el segundo al ejecutarlo 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 utiliza a través de JDBC, aunque no funcione en la columna y aunque parezca estar funcionando en SQL Developer?
Es muy posible que tenga problemas con el pico de variable de enlace debido a los predicados que se pasan. Intente ejecutar la consulta con lo siguiente para confirmar (es decir, tiempos de ejecución consistentes)
alter session set “_optim_peek_user_binds”=false;
¿Están las estadísticas actualizadas en todos los objetos?
Como justin también publicó, asegúrese de que también esté midiendo correctamente. Sin la consulta completa, será difícil proporcionar información adicional.
Intentaría rastrear la base de datos mientras usaba la aplicación.
Entonces debería poder ver la consulta que se está ejecutando y el plan de ejecución real. Esto le mostrará exactamente lo que está sucediendo, es decir, si está recogiendo los índices o no.
Compruebe para asegurarse de que alguien no haya configurado la propiedad oracle.jdbc.defaultNChar = true
Esto a veces se hace para resolver problemas Unicode pero significa que todas las columnas se tratan como nvarchars. Si tiene un índice en una columna varchar, no se usará porque Oracle tiene que usar una función para convertir la codificación de caracteres.