¿Existe una diferencia de rendimiento entre estas dos consultas de ejemplo?
Consulta 1:
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y'
Consulta 2;
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
and b.tag = 'Y'
Observe que la única diferencia es la ubicación de la condición suplementaria; el primero usa una WHERE
cláusula y el segundo agrega la condición a la ON
cláusula.
Cuando ejecuto estas consultas en mi sistema Teradata, los planes de explicación son idénticos y el paso UNIR muestra la condición adicional en cada caso. Sin embargo, en esta pregunta SO con respecto a MySQL, una de las respuestas sugirió que se prefiere el segundo estilo porque el WHERE
procesamiento ocurre después de que se realizan las uniones.
¿Hay una regla general a seguir al codificar consultas como esta? Supongo que debe depender de la plataforma, ya que obviamente no hace ninguna diferencia en mi base de datos, pero tal vez eso sea solo una característica de Teradata. Y si es dependiente de la plataforma, me gustaría mucho conseguir algunas referencias de documentación; Realmente no sé qué buscar.
fuente
Respuestas:
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:
ORDER BY
yGROUP BY
.En esa misma página, dice lo siguiente:
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
Jan 23, 2013
: Problema con consultas de ACTUALIZACIÓN anidadasFeb 22, 2011
: Problema con la subconsulta MySQLporque 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.
Probablemente tendría que forzar el orden de ejecución reescribiendo (refactorizando) la consulta
Aquí está la primera consulta que diste
Intente reescribirlo para evaluar el DÓNDE primero
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.
fuente
Para Oracle, dado que mySQL tenía una descripción extensa, tenemos 2 formas de alto nivel de aprovechar el optimizador.
Primero es la optimización basada en reglas (o RBO). Oracle tiene 15 reglas establecidas que cada consulta que analiza intenta seguir en un orden establecido. Si no puede generar una consulta optimizada a partir de la regla 1, avanzará a la regla 2 y avanzará hasta que llegue a la regla 15.
Para más información: https://docs.oracle.com/cd/B10500_01/server.920/a96533/rbo.htm
Estos afectan a los núcleos Oracle RDBMS de 11.1 e inferiores que no se han convertido al Optimizador basado en costos (también conocido como CBO). Oracle 11.2 y versiones posteriores requieren el optimizador CBO, pero pueden forzar la identificación específica de SQL para optimizar en el antiguo método RBO si el usuario lo desea.
El CBO para Oracle 11.1+ en su lugar hace varios planes de ejecución para la misma ID de SQL y ejecuta el que tiene el menor costo total previsto. Aprovecha gran parte de la lógica de RBO, pero analiza las estadísticas de la tabla para crear costos de planes de ejecución dinámicos para cada operación que la base de datos tiene que hacer para proporcionar sus datos al usuario final. Ejecutar escaneos completos de tablas en tablas muy grandes es realmente costoso; Ejecutar escaneos completos de tablas en una tabla con 10 filas es barato. En RBO, estas se consideraron operaciones iguales.
Para más información: https://oracle-base.com/articles/misc/cost-based-optimizer-and-database-statistics
Para su ejemplo de consulta específica: es probable que Oracle analice la información para hacer diferentes planes de ejecución y, por lo tanto, uno será técnicamente mejor que el otro. Sin embargo, esto puede ser una diferencia mínima. Al observarlo, tanto Oracle RBO como CBO desearían consultar 1 más porque se ejecuta en una unión en menos condiciones y luego filtra una columna específica de la tabla temporal que hizo desde la unión.
fuente
Si tiene dos consultas y cree que son equivalentes, puede ocurrir lo siguiente:
Existen diferentes planes de ejecución. Tenemos dos subcajas aquí.
2.1 Las consultas tienen diferentes planes de ejecución, pero ambos planes funcionan igual de bien. Eso también está bien. No es necesario que para consultas equivalentes se genere el mismo plan. Pero el rendimiento debe ser igual. Y de nuevo esperamos que sea lo mejor posible.
2.2 Las consultas tienen diferentes planes de ejecución y un plan es mejor que el otro. Nuevamente tenemos subcasas:
2.2.1 Los planes son diferentes porque las consultas no son equivalentes. Por lo tanto, compruebe cuidadosamente si son realmente equivalentes. En tu caso son realmente equivalentes.
2.2.2 Los planes son diferentes pero las consultas son equivalentes. Esto significa que el optimizador no ha madurado lo suficiente. En un mundo perfecto con optimizadores perfectos, esto no debería suceder. Entonces, sí, depende de la plataforma y debe estudiar documentos específicos de la plataforma para descubrir por qué sucede esto.
2.2.3 Los planes son diferentes, las consultas son equivalentes, el software de la base de datos tiene un error.
fuente