Estoy intentando comprender mejor por qué esta optimización de consultas es tan significativa (más de 100 veces más rápida), así que puedo reutilizar una lógica similar para otras consultas.por qué MySQL JOIN es significativamente más rápido que WHERE IN (subconsulta)
Uso de MySQL 4.1 - RESET QUERY CACHE y FLUSH TABLES se realizaron antes de que todas las consultas y el tiempo de resultado se puedan reproducir de forma consistente. Lo único que es obvio para mí en el EXPLAIN es que solo se deben encontrar 5 filas durante el JOIN? ¿Pero esa es la respuesta completa a la velocidad? Ambas consultas están utilizando un índice parcial (forum_stickies) para determinar el estado de los temas Suprimido (topic_status = 0)
Imágenes para el análisis más profundo con EXPLAIN
consulta lenta: 0.7+ segundo (caché despejado)
SELECT SQL_NO_CACHE forum_id, topic_id FROM bb_topics
WHERE topic_last_post_id IN
(SELECT SQL_NO_CACHE MAX (topic_last_post_id) AS topic_last_post_id
FROM bb_topics WHERE topic_status=0 GROUP BY forum_id)
consulta rápida: 0.004 segundos o menos (caché borra)
SELECT SQL_NO_CACHE forum_id, topic_id FROM bb_topics AS s1
JOIN
(SELECT SQL_NO_CACHE MAX(topic_last_post_id) AS topic_last_post_id
FROM bb_topics WHERE topic_status=0 GROUP BY forum_id) AS s2
ON s1.topic_last_post_id=s2.topic_last_post_id
cuenta que no hay índice en la columna más importante (topic_last_post_id
), pero que no se puede evitar (los resultados se almacenan para su uso repetido de todos modos).
¿Es la respuesta simplemente porque la primera consulta tiene que escanear topic_last_post_id
DOS VECES, la segunda vez para hacer coincidir los resultados con la subconsulta? Si es así, ¿por qué es exponencialmente más lento?
(menos importantes Tengo curiosidad por qué la primera consulta todavía lleva tanto tiempo si realmente no poner un índice en topic_last_post_id
)
actualización: He encontrado este hilo en stackoverflow después de mucho buscar posterior en que entra en este tema Subqueries vs joins
Wow eso podría ser posible. Solo había considerado que tal vez hace la consulta para cada uno de los id en los resultados del grupo (5 de ellos) pero ahora que lo mencionas, me pregunto si lo hace para las 209 (o incluso para las 293) filas. Envié una solicitud a alguien para intentar las consultas en un conjunto de datos mucho más grande (10.000 filas frente a 300) para ver si el problema se magnifica aún más, lo que probaría la teoría. –
Me acaba de ocurrir que también intente esto simplemente consulta 'SELECT SQL_NO_CACHE forum_id, topic_id FROM bb_topics WHERE topic_last_post_id IN (1516,1567,1572,1569,1578)' y es extremadamente rápido. Así que tienes razón, está ejecutando la subconsulta para cada fila, ¡vaya! Eso es una locura. –
Esto parece estar solucionado en 5.6 (ya no es una "SUBCONTRIA DEPENDIENTE"), y el rendimiento es similar a un JOIN. – Vatev