Pregunta

De repente (pero por desgracia no sé cuando "de repente" estaba; sé que funcionó muy bien en algún momento en el pasado) una de mis consultas comenzó a tomar más de 7 segundos en lugar de milisegundos en ejecutarse. Tengo 1 tabla local y 3 mesas que se accede a través de un enlace de DB. Las 3 tablas remotas se unen entre sí, y uno de ellos se unieron con mi tabla local.

La tabla local es que la cláusula sólo toma unos millis para ejecutar por sí mismo, y sólo devuelve unos pocos (10 de 100 o de a lo sumo) registros. Las 3 tablas remotas tienen muchos cientos de miles, posiblemente millones de registros, entre ellos, y si me uno a ellos apropiadamente que reciben decenas o cientos de miles de registros.

Yo sólo estoy uniendo con las tablas remotas para que pueda sacar algunas piezas de los datos relacionados con cada registro en mi tabla local.

Lo que parece estar sucediendo, sin embargo, es que Oracle se une a las tablas remotas juntos primero y luego mi tabla local a ese lío al final. Esto siempre va a ser una mala idea, especialmente teniendo en cuenta el conjunto de datos que existe en este momento, por lo que añade un toque /*+ LEADING(local_tab remote_tab_1) */ a mi consulta y que ahora vuelve en milisegundos.

Me comparó la explican planes y son casi idénticos, salvo por una sola BUFFER SORT en una de las tablas remotas.

Me pregunto lo que podría causar Oracle para acercarse a mal? ¿Es un problema de índice? ¿Qué debo buscar?

¿Fue útil?

Solución

Al elegir un plan de ejecución, Oracle calcula los costes para los diferentes planes. Una información crucial para que la estimación es la cantidad de filas conseguirá regresar de un paso del plan de ejecución. Oracle intenta estimar los que utilizan las estadísticas '', es decir, la información sobre el número de filas de una tabla contiene, ¿cuántas diferentes valores de una columna contiene; ¿Cómo se distribuyen uniformemente estos valores.

Estas estadísticas son sólo eso estadísticas, y que podría estar equivocado, que es una de las razones más importantes para los errores de juicio del optimizador de Oracle.

Así que la recopilación de nuevas estadísticas como se describe en una ayuda comentario fuerzas. Echar un vistazo a la documentación sobre ese paquete DBMS_STATS. Hay muchas maneras diferentes de llamar a ese paquete.

Otros consejos

Un problema común que he encontrado es una consulta que combina muchas mesas, donde las uniones formar una cadena de un extremo a otro, por ejemplo:.

SELECT *
FROM   tableA, tableB, tableC, tableD, tableE
WHERE  tableA.ID0 = :bind1
AND    tableA.ID1 = tableB.ID1
AND    tableB.ID2 = tableC.ID2
AND    tableC.ID3 = tableD.ID3
AND    tableD.ID4 = tableE.ID4
AND    tableE.ID5 = :bind2;

Aviso cómo el optimizador puede elegir para conducir la consulta de la Tabla A (por ejemplo, si el índice en ID0 es bien selectiva) o desde Tablee (si el índice en tableE.ID5 es más selectivo).

Las estadísticas sobre las mesas podría causar la elección entre estos dos planes para mantener el equilibrio sobre el borde del precipicio; Un día es fino (la conducción de la Tabla A), al día siguiente de trabajo nuevas estadísticas son recogidos y, de repente, el plan alternativo de conducción de Tablee tiene un costo más bajo y es elegido.

En esta circunstancia, la adición de un toque de ataque es una manera para empujar de nuevo al plan original (es decir, la unidad de la Tabla A) sin imponer demasiado al optimizador (es decir, que no obliga al optimizador de elegir cualquier particular, se unen a los métodos).

Lo estás haciendo optimización de consultas distribuidas, y eso es una bestia difícil. Podría ser que las estadísticas de la su mesa están al día, pero ahora las mesas en el sistema remoto están fuera de whack o han cambiado. O el sistema remoto añadido / eliminado índices / modificados, y que rompió su plan. (Esta es una excelente razón para considerar la replicación -. Para que pueda controlar los índices y las estadísticas en contra de ella)

Dicho esto, estimación de cardinalidad de Oracle es un factor principal en el plan de ejecución. Un análisis 10053 trace (costes sobre la base Jonathan Lewis libro Fundamentos de Oracle tiene maravillosos ejemplos de 8i a 10.1) ayuda puede arrojar luz sobre por qué su estado de cuenta ahora está rota y cómo los LEADING indirecta arregla.

La sugerencia DRIVING_SITE podría ser una mejor opción si usted sabe que siempre desea que las tablas locales a unir primero antes de ir después de que el sitio remoto; aclara que su intención sin tener que manejar el plan de la manera en una pista LEADING haría.

Puede que no sea relevante, pero tuve una situación similar una vez en la tabla remota había sido reemplazada por una vista de una sola mesa. Cuando se trataba de una mesa de la consulta optimizador 'sierra' distribuido que tenía un índice. Cuando se convirtió en un punto de vista que no podía ver el índice más y no podía costar un plan que utiliza un índice en el objeto remoto.

Eso era hace unos años. Documenté mi análisis en el momento aquí .

RI,

Es difícil estar seguro acerca de la causa de los problemas de rendimiento sin ver el SQL.

Cuando una consulta de Oracle estaba llevando a cabo mucho antes, y de repente empieza a realizar mal, por lo general se relaciona con uno de dos cuestiones:

  

a) estadísticas no están actualizadas. Esta es la cosa más fácil y más rápida para comprobar, incluso si tiene un proceso por lotes de limpieza que se supone que cuidar de él ... siempre doble verificación.

     

B) Volumen de datos / cambio en el patrón de datos.

En su caso, se ejecuta una consulta distribuida a través de múltiples bases de datos hace que sea más difícil 10x para Oracle para gestionar el rendimiento entre ellos. ¿Es posible poner estas tablas en una base de datos, los propietarios de esquema tal vez separados en una base de datos?

Las sugerencias son notoriamente frágiles, como Oracle está bajo ninguna obligación de seguir la pista. Cuando el volumen de datos o patrón cambia un poco más, Oracle puede simplemente ignorar el mensaje y hacer lo que piensa que es mejor (es decir, peor; -.).

Si no se puede poner estas tablas todo en una base de datos, entonces le recomiendo que mire a romper su consulta en dos estados:

  1. INSERT en el sub-SELECT para copiar datos externos a una tabla temporal global en su base de datos actual.
  2. SELECT de la tabla temporal global para unirse con la otra tabla.

tendrá un control completo sobre el rendimiento de la etapa 1 anterior sin tener que recurrir a las indirectas. Este enfoque suele escala bien, siempre y cuando se tome tiempo para hacer el ajuste del rendimiento. He visto este enfoque a resolver muchos problemas de rendimiento compleja.

La sobrecarga para Oracle para crear una tabla nueva, o insertar un montón de registros, es mucho más pequeña que la mayoría de la gente espera. Definición de una tabla temporal global reduce aún más que los gastos generales.

Matthew

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top