2010-09-07 154 views
6

Usamos ODP.NET para realizar consultas en bases de datos Oracle, y normalmente funciona bien. Sin embargo, hay una base de datos particular y una vista particular en esa base de datos que simplemente no podemos completar una consulta desde .NET. Por ejemplo:La consulta de Oracle es lenta (o falla) desde la aplicación .NET pero es rápida desde SQL Developer

SELECT some_varchar_field FROM the_view WHERE ROWNUM < 5; 

Si ejecuto esta consulta desde Oracle SQL Developer, termina en menos de un segundo. Si realizo una consulta idéntica desde nuestra aplicación .NET utilizando ODP.NET, se cuelga y finalmente produce un error "ORA-03135: conexión perdida de contacto". Creo que limitarlo a solo unas pocas filas elimina la posibilidad de que sea un problema de FetchSize.

Existen otras consultas que puedo ejecutar con éxito, pero son más lentas desde nuestro programa que desde SQL Developer. De nuevo, me doy cuenta de que SQL Developer solo obtiene datos para las primeras 50 filas inicialmente, pero creo que la condición ROWNUM lo elimina de la ecuación.

¿Qué podría ser diferente acerca de la conexión o el comando que usa Oracle SQL Developer frente al que está usando nuestra aplicación que causaría una diferencia en la velocidad?

Desafortunadamente, no tengo acceso al servidor (que no sea para ejecutar consultas de Oracle en su contra).

Gracias.

ACTUALIZACIÓN: He intentado la misma consulta con el proveedor Oracle de Microsoft y se ejecuta muy rápidamente. Lamentablemente, ese proveedor está en desuso, por lo que esta no es una solución a largo plazo.

Respuesta

9

No tiene nada que ver con el proveedor ODP.NET. El problema fue que la biblioteca que utilizamos para crear conexiones para nosotros (que, por supuesto, Oracle SQL Developer no usa, y que no usé cuando probé el proveedor de Microsoft) siempre estaba ejecutando las siguientes declaraciones antes de hacer algo:

ALTER SESSION SET NLS_COMP = LINGUISTIC 
ALTER SESSION SET NLS_SORT = BINARY_CI 

Esto hace que Oracle no distinga entre mayúsculas y minúsculas. Pero también hacen que todos los índices convencionales sean inútiles. Debido a que estábamos consultando desde una Vista, tenía incorporado el pedido. Y como no poseemos la base de datos, no podemos hacer que los índices sean lingüísticos para solucionar el problema de rendimiento.

Proporcionar una forma de no ejecutar esas declaraciones en este (raro) escenario solucionado el problema.

+0

En adición a esta MUY respuesta útil, encontré que ejecuta ALTER SESSION SET NLS_COMP = BINARY; ALTER SESSION SET NLS_SORT = BINARIO; establecer la sesión de nuevo su configuración predeterminada. Claro, activa la distinción entre mayúsculas y minúsculas, pero eso no es tan malo como las consultas lentas. –

+0

¿Cómo descubrió que la biblioteca que está utilizando estaba ejecutando esas declaraciones? Estoy teniendo un escenario similar: al instante en Oracle Sql Developer, pero a pocos segundos de la aplicación. Probar exactamente el mismo escenario en Sql Server es realmente más rápido. Tal vez me falta una configuración importante. –

4

pensamientos inmediatos son

  1. CLOB, BLOB o LONG/LONG RAW que requiere una gran cantidad de ancho de banda por sólo unas pocas filas.
  2. Datos no válidos (por ejemplo, hay formas de obtener una fecha no válida en un campo de fecha, lo que puede confundir a algunos clientes)
  3. "the_table" no es realmente una tabla sino una vista o algo con una derivación compleja o tiene una Política de seguridad VPD/RLS/FGAC en él.
  4. Tipo de datos exótico (espacial o definido por el usuario).

Sugerencias

  1. explícitamente una lista de las columnas (por ejemplo, SELECT a, b, c DE the_table DONDE ROWNUM < 5). Agregue columnas una por una hasta que deje de funcionar. Eso supone que hay al menos una columna 'simple' en la tabla.
  2. Compruebe la sesión en v $ session para ver qué espera es EVENT. O bien el servidor de bases de datos está grabando CPU para este SQL, o está esperando algo (posiblemente el cliente).
  3. Compruebe el SQL en v $ sql. ¿Hay uno o más cursores secundarios? ¿Hay uno o más PLAN_HASH_VALUEs? Los diferentes cursores secundarios pueden usar diferentes planes. Sin una cláusula WHERE que no sea ROWNUM, esto es bastante improbable.
+0

¿También valdría la pena verificar el registro de alertas del servidor para ver si hay un ORA-600 para ir con el ORA-03135 para esta consulta? –

+0

He actualizado la pregunta en respuesta a su respuesta. Además, solo hay campos simples (el campo más grande es varchar2 (576)), y el problema ocurre incluso si selecciono solo un campo. Tienes razón de que en realidad es una Vista. –

0

En un proyecto en el que estaba trabajando en mi antiguo empleador, estábamos usando odp.net para hablar con una gran base de datos del sistema de venta minorista y nos daban errores de conexión perdidos.

Tomó un gran esfuerzo para probar, pero terminó siendo un índice corrupto dentro de la base de datos Oracle que solo estaba siendo afectado por nuestra consulta.El DBA eventualmente lo remontó a un núcleo del proceso que se ejecuta en el cuadro de Sun cuando se estaba ejecutando nuestra consulta. No usamos ningún tipo de sugerencia de consulta, etc., pero cuando ejecutamos la misma consulta en Toad, no alcanzó este índice en particular. ¿¿extraño?? < <

1

Una vista agrega una magnitud diferente de complejidad. A "SELECCIONAR columna FROM table WHERE rownum < 5" tiene probablemente solo un único plan de explicación, seleccionando datos de un solo objeto local.

Para una vista que debe empezar por conseguir la vista de texto SELECT TEXT FROM ALL_VIEWS WHERE VIEW_NAME = ...

Hay muchas cosas que pueden ser diferentes entre un ODP.NET y una sesión de SQL Developer. Pensaría en los parámetros de NLS (como los formatos de fecha) y la configuración del juego de caracteres.

Si puede ubicar el SQL en v $ sql, puede hacer un DBMS_XPLAN.DISPLAY_CURSOR (sql_id) para ver los diferentes planes y ver si puede identificar el problema.

Cuestiones relacionadas