He estado perfilando algunas consultas en una aplicación en la que estoy trabajando, y encontré una consulta que estaba recuperando más filas de las necesarias, y el conjunto de resultados se recortó en el código de la aplicación.Left Unirse para ver el logro Inner Join?
Al cambiar una UNIÓN IZQUIERDA a una UNIÓN INTERIOR se recortó el conjunto de resultados a justo lo que se necesitaba, y presumiblemente también sería más eficiente (ya que se seleccionaron menos filas). En realidad, la consulta LEFT JOIN'ed estaba superando a INNER JOIN'ed, tomando la mitad del tiempo para completarla.
LEFT JOIN: (127 filas totales, Consulta tomó 0,0011 seg)
INNER JOIN: (10 filas totales, Consulta tomó 0,0024 seg)
(I corrieron las consultas múltiples veces y aquellos son promedios) .
Correr explique en tanto no revela nada que explica las diferencias de rendimiento:
Para la combinación interna:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1 Using where
Para la combinación izquierda:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE contacts index NULL name 302 NULL 235 Using where
1 SIMPLE lists eq_ref PRIMARY PRIMARY 4 contacts.list_id 1
1 SIMPLE lists_to_users eq_ref PRIMARY PRIMARY 8 lists.id,const 1
1 SIMPLE tags eq_ref PRIMARY PRIMARY 4 lists_to_users.tag_id 1
1 SIMPLE users eq_ref email_2 email_2 302 contacts.email 1
Y la propia consulta:
SELECT `contacts`.*, `lists`.`name` AS `group`, `lists`.`id` AS `group_id`, `lists`.`shared_yn`, `tags`.`name` AS `context`, `tags`.`id` AS `context_id`, `tags`.`color` AS `context_color`, `users`.`id` AS `user_id`, `users`.`avatar`
FROM `contacts`
LEFT JOIN `lists` ON lists.id=contacts.list_id
LEFT JOIN `lists_to_users` ON lists_to_users.list_id=lists.id AND lists_to_users.user_id='1' AND lists_to_users.creator='1'
LEFT JOIN `tags` ON tags.id=lists_to_users.tag_id
INNER JOIN `users` ON users.email=contacts.email
WHERE (contacts.user_id='1')
ORDER BY `contacts`.`name` ASC
(La cláusula de la que estoy hablando es la ÚLTIMA UNIÓN INTERNA en la tabla 'usuarios')
La consulta se ejecuta en una base de datos MySQL 5.1, si hace una diferencia.
¿Alguien tiene una pista sobre por qué la consulta LEFT JOIN'ed supera a INNER JOIN'ed en este caso?
ACTUALIZACIÓN: Debido a la sugerencia de Tomalak que las pequeñas mesas que estoy usando estaban haciendo en la unión interna más compleja, que había creado una base de datos de prueba con algunos datos simulados. La tabla de 'usuarios' tiene 5000 filas y la tabla de contactos tiene ~ 500,000 filas. Los resultados son los mismos (también los tiempos no han cambiado, lo que es sorprendente si tenemos en cuenta que las tablas son mucho más grandes ahora).
También ejecuté ANALYZE y OPTIMIZE en la tabla de contactos. No hizo ninguna diferencia discernible.
¿Intentó colocar primero la unión interna? –
Tengo, acelera esa consulta en un 20%, pero aún más lenta que la UNIÓN IZQUIERDA –
Intenta compilar cada consulta secuencialmente (unir una tabla, medir, unir la siguiente, etc.) Tal vez esto te ayude a determinar la operación lenta . – Tomalak