2009-11-27 36 views
11

Entonces ... cuál es más rápido (el valor NULl no es un problema) y está indexado.Izquierda JOIN más rápido o Inner Join más rápido?

SELECT * FROM A 
    JOIN B b ON b.id = a.id 
    JOIN C c ON c.id = b.id 
WHERE A.id = '12345' 

Usando izquierda se une a:

SELECT * FROM A 
LEFT JOIN B ON B.id=A.bid 
LEFT JOIN C ON C.id=B.cid 
WHERE A.id = '12345' 

Ésta es la consulta real Aquí es .. ambos devuelven el mismo resultado

Query (0.2693sec) : 
    EXPLAIN EXTENDED SELECT * 
    FROM friend_events, zcms_users, user_events, 
    EVENTS WHERE friend_events.userid = '13006' 
    AND friend_events.state =0 
    AND UNIX_TIMESTAMP(friend_events.t) >=1258923485 
    AND friend_events.xid = user_events.id 
    AND user_events.eid = events.eid 
    AND events.active =1 
    AND zcms_users.id = user_events.userid 

EXPLAIN 

    id select_type table type possible_keys key key_len ref rows Extra 
    1 SIMPLE zcms_users ALL PRIMARY NULL NULL NULL 43082 
    1 SIMPLE user_events ref PRIMARY,eid,userid userid 4 zcms_users.id 1 
    1 SIMPLE events eq_ref PRIMARY,active PRIMARY4 user_events.eid 1 Using where 
    1 SIMPLE friend_events eq_ref PRIMARY PRIMARY 8 user_events.id,const 1 Using where 



    LEFTJOIN QUERY: (0.0393 sec) 

    EXPLAIN EXTENDED SELECT * 
    FROM `friend_events` 
    LEFT JOIN `user_events` ON user_events.id = friend_events.xid 
    LEFT JOIN `events` ON user_events.eid = events.eid 
    LEFT JOIN `zcms_users` ON user_events.userid = zcms_users.id 
    WHERE (
    events.active =1 
    ) 
    AND (
    friend_events.userid = '13006' 
    ) 
    AND (
    friend_events.state =0 
    ) 
    AND (
    UNIX_TIMESTAMP(friend_events.t) >=1258923485 
    ) 


EXPLAIN 
    id select_type table type possible_keys key key_len ref rows Extra 
    1 SIMPLE friend_events ALL PRIMARY NULL NULL NULL 53113 Using where 
    1 SIMPLE user_events eq_ref PRIMARY,eid PRIMARY 4 friend_events.xid 1 Using where 
    1 SIMPLE zcms_users eq_ref PRIMARY PRIMARY 4 user_events.userid 1 
    1 SIMPLE events eq_ref PRIMARY,active PRIMARY 4 user_events.eid 1 Using where 
+1

¿Por qué no ejecuta ambos y nos dice que es más rápido? – Welbog

+0

Esta pregunta debe reformularse, "¿Cómo puedo averiguar qué consulta se ejecuta más rápido?" –

+0

¿Estos eventos devuelven el mismo conjunto de resultados? (columnas, no filas) – JMD

Respuesta

9

Depende; ejecutarlos a ambos para descubrir; luego ejecuta un 'explicar selección' para una explicación.

La diferencia de rendimiento real puede variar desde "prácticamente inexistente" a "muy significativa", dependiendo de cuántas filas en A con id = '12345' no tienen registros coincidentes en B y C.

actualización (basado en planes de consultas publicados)

Cuando utiliza INNER JOIN, no importa (en lo que respecta a los resultados, no al rendimiento) con qué tabla comenzar, por lo que el optimizador intenta elegir el que cree que funcionará mejor . Parece que tiene índices en todas las columnas PK/FK apropiadas y que no tiene un índice en friend_events.userid o que hay demasiados registros con userid = '13006' y que no se está utilizando; El optimizador de cualquier forma selecciona la tabla con menos filas como "base", en este caso es zcms_users.

Cuando usa UNIÓN IZQUIERDA hace materia (resultados) con qué tabla comenzar; por lo tanto, se elige friend_events. Ahora por qué toma menos tiempo de esa manera, no estoy del todo seguro; Supongo que la condición friend_events.userid ayuda. Si tuviera que agregar un índice (¿es realmente varchar, por cierto, no es numérico?), Su INNER JOIN podría comportarse de manera diferente (y volverse más rápida) también.

+0

Lo he ejecutado. parece que el interno es mucho más lento. pero ¿no es que lo interno debería ser mejor que unirse a la izquierda? – Murvinlai

+0

¿Puedes publicar los resultados de "explicar seleccionar" para ambas consultas? – ChssPly76

2

Usa EXPLAIN para ver el plan de consultas. Probablemente sea el mismo plan para ambos casos, así que dudo que haga mucha diferencia, suponiendo que no haya filas que no coincidan. Pero estas son dos consultas diferentes, por lo que no tiene sentido compararlas; solo debe usar la correcta.

¿Por qué no utilizar la palabra clave "INNER JOIN" en lugar de "LEFT JOIN"?

3

INNER JOIN tiene que hacer una comprobación adicional para eliminar los registros de A que no tienen registros coincidentes en B y C. Dependiendo de la cantidad de registros inicialmente devueltos desde A, PODRÍA tener un impacto.

1

LEFT JOIN muestra todos los datos de A y solo muestra los datos de B/C solo si la condición es verdadera. En cuanto a INNER JOIN, tiene que hacer algunas comprobaciones adicionales en ambos tables. Entonces, supongo que eso explica por qué LEFT JOIN es más rápido.