2011-02-07 17 views
11

Un sistema antiguo ha llegado a nuestra oficina para algunos cambios y arreglos, pero también está sufriendo problemas de rendimiento. No sabemos exactamente cuál es la fuente de esta lentitud.¿Qué es mejor? ¿Subconsultas o internas que unen diez tablas?

Mientras estábamos refactorización del antiguo código encontramos varias consultas SQL con el patrón de seguimiento (las consultas se simplifican con fines de ejemplo):

SELECT 
    (
    SELECT X 
    FROM A 
    WHERE A.id = TABLE.id 
    ) AS COLUMN1, 
    (
    SELECT Y 
    FROM B 
    WHERE B.id = TABLE.id 
    ) AS COLUMN1, 
    (
    SELECT Z 
    FROM C 
    WHERE C.id = TABLE.id 
    ) AS COLUMN1, 
    ... 
FROM 
    TABLE 
WHERE 
    TABLE.id = @param; 

Estas consultas hacen varias consultas sub internos de cada columna que regreso.

estamos pensando en volver a escribir estas consultas en el patrón de la siguiente manera:

SELECT 
    A.X, B.Y, C.Z 
FROM 
    TABLE 
    INNER JOIN A on A.ID = TABLE.ID 
    INNER JOIN B on B.ID = TABLE.ID 
    INNER JOIN C on C.ID = TABLE.ID 
WHERE 
    TABLE.id = @param; 

Con combinaciones internas son más fácil de leer y entender, pero ¿es realmente más rápido? ¿Es la mejor manera de escribirlos? Lamentablemente, el primero que reescribimos no mejoró el tiempo de consulta, hizo que la consulta fuera un poco más lenta.

Aquí está mi pregunta: ¿deberíamos reescribir todas estas consultas? ¿Estas subconsultas son una buena forma de hacer este trabajo? ¿Son más rápidos el camino de la unión interior?

+0

Tom (Kyte, de la fama de Oracle) dio una buena (y breve) respuesta a una pregunta muy similar aquí: ["une vs subquery, existe cláusula"] (https://asktom.oracle.com/pls/asktom/f? p = 100: 11: 0 :::: P11_QUESTION_ID: 66812779016023) –

Respuesta

14

Si entiendo su pregunta correctamente, está iniciando una operación para reescribir algunas de sus declaraciones SQL porque PIENSA que podría haber un problema con ellas.

Mi consejo es detenerse y comenzar a determinar dónde se está gastando su tiempo. Solo después de que haya encontrado que está en las consultas con esas subsecuencias escalares Y es debido a esas subsecuencias escalares, debe volver a escribirlas. Hasta entonces: comience a rastrear y examinar.

Aquí hay dos hilos de OTN que se utilizan para guiar a las personas con problemas de rendimiento:

http://forums.oracle.com/forums/thread.jspa?messageID=1812597 http://forums.oracle.com/forums/thread.jspa?threadID=863295

Saludos,
Rob.

Y: debido a scalar subquery caching, su consulta original puede ser mucho más rápida que una consulta reescrita utilizando combinaciones.

+1

Tu respuesta me dijo exactamente algo sobre lo que no estaba seguro: "almacenamiento en caché de subconsulta escalar". Tal vez las consultas secundarias pueden ser buenas a veces. Sin embargo, volvimos a escribir otra consulta y obtuvimos un resultado realmente mejor, de 0,5 s a 0,04 s. Estoy firmando su publicación como la correcta, porque para algunas personas las consultas secundarias tal vez sean una buena solución. Gracias. –

7

subconsulta en realidad se ejecuta una vez por cada fila, mientras que la unión se produce en los índices.

Use combinaciones para una mejor legibilidad y facilidad de mantenimiento como ya ha mencionado en sus preguntas.

+0

¿Por qué? si hay un índice, se debe aplicar a una búsqueda de identificación simple. –

+0

En ocasiones, la tabla no está unida por sus columnas indizadas. ¿Afecta esto la preferencia por la unión interna? –

+3

@ Adam, @ Gustavo - El rendimiento depende del motor de base de datos con el que ejecuta las consultas. Debe verificar el rendimiento utilizando el plan de ejecución (no estoy seguro de cómo se llama exactamente en Oracle). A veces, las subconsultas son mejores, a veces se unen, pero finalmente para una mejor legibilidad y mantenimiento de consultas, las uniones tienen una ligera ventaja. –

3

Las uniones le darán un mejor rendimiento, pero le recomiendo que consulte el plan de ejecución cada vez que "optimice" las consultas.

+0

Debería vigilar el plan, gracias. No hay un ajuste real sin medir el resultado. –

2

Como this answer argues, debería no afecta el rendimiento. Sin embargo, algunos optimizadores de consultas pueden funcionar mejor en JOINs, por lo que debe realizar algunos experimentos en su sistema.

Y ahora algo completamente diferente: JOIN ing cada tabla a la siguiente podría ser más estético que JOIN ing todos con TABLE, y evita errores cada vez que el ID aparece más de una vez en una de las mesas:

SELECT 
    A.X, B.Y, C.Z 
FROM 
    TABLE 
    INNER JOIN A on A.ID = TABLE.ID 
    INNER JOIN B on A.ID = B.ID 
    INNER JOIN C on B.ID = C.ID 
WHERE 
    TABLE.id = @param; 
+0

Gracias por el ejemplo. Por supuesto, es mejor leer. En mi ejemplo solo hay 3 uniones, pero cada consulta aquí lo hace 10 o más veces por consulta ... –

Cuestiones relacionadas