De acuerdo con el Capítulo 9 (Analizador y Optimizador), Página 172 del Libro Comprensión de MySQL Internals por Sasha Pachev
Aquí está el desglose de la evaluación de una consulta como las siguientes tareas:
- Determine qué claves se pueden usar para recuperar los registros de las tablas y elija la mejor para cada tabla.
- Para cada tabla, decida si una exploración de tabla es mejor que leer en una clave. Si hay muchos registros que coinciden con el valor de la clave, las ventajas de la clave se reducen y el escaneo de la tabla se vuelve más rápido.
- Determine el orden en el que se deben unir las tablas cuando hay más de una tabla presente en la consulta.
- Vuelva a escribir las cláusulas WHERE para eliminar el código muerto, reduciendo los cálculos innecesarios y cambiando las restricciones siempre que sea posible para abrir el camino para el uso de claves.
- Elimine las tablas no utilizadas de la unión.
- Determine si las teclas se pueden usar para
ORDER BY
y GROUP BY
.
- Intente simplificar las subconsultas y determine en qué medida se pueden almacenar en caché sus resultados.
- Combinar vistas (expanda la referencia de vista como una macro)
En esa misma página, dice lo siguiente:
En la terminología del optimizador MySQL, cada consulta es un conjunto de combinaciones. El término join se usa aquí más ampliamente que en los comandos SQL. Una consulta en una sola tabla es una unión degenerada. Si bien normalmente no pensamos en leer registros de una tabla como una combinación, las mismas estructuras y algoritmos utilizados con las combinaciones convencionales funcionan perfectamente para resolver la consulta con una sola tabla.
EPÍLOGO
Debido a las claves presentes, la cantidad de datos y la expresión de la consulta, MySQL Joins a veces puede hacer cosas por nuestro propio bien (o para responder a nosotros) y obtener resultados que no esperábamos y que no podemos explicar rápidamente.
Escribí sobre esta peculiaridad antes
porque MySQL Query Optimizer podría hacer que se descarten ciertas claves durante la evaluación de la consulta.
El comentario de @ Phil me ayudó a ver cómo publicar esta respuesta (+1 para el comentario de @ Phil)
El comentario de @ypercube (+1 para este también) es una versión compacta de mi publicación porque el Optimizador de consultas de MySQL es primitivo. Desafortunadamente, tiene que ser ya que se trata de motores de almacenamiento externos.
CONCLUSIÓN
En cuanto a su pregunta real, MySQL Query Optimizer determinaría las métricas de rendimiento de cada consulta cuando se realice.
- contando filas
- seleccionando teclas
- masajear conjuntos de resultados intermitentes
- Oh sí, haciendo la UNIÓN real
Probablemente tendría que forzar el orden de ejecución reescribiendo (refactorizando) la consulta
Aquí está la primera consulta que diste
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Intente reescribirlo para evaluar el DÓNDE primero
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Eso definitivamente alteraría el plan EXPLICAR. Podría producir mejores o peores resultados.
Una vez respondí una pregunta en StackOverflow donde apliqué esta técnica. El EXPLICAR fue horrendo pero el rendimiento fue dinamita. Solo funcionó por tener los índices correctos presentes y el uso de LIMIT en una subconsulta .
Al igual que con los precios de las acciones, cuando se trata de consultas e intentar expresarlas, se aplican restricciones, los resultados pueden variar y el rendimiento pasado no es indicativo de resultados futuros.