sql >> Base de Datos >  >> RDS >> Mysql

ÚNETE frente a DÓNDE:¿Por qué dos consultas que obtienen resultados idénticos presentan una diferencia de rendimiento de 3 o 4 órdenes de magnitud?

MySQL tiene problemas conocidos con la optimización de consultas que involucran subconsultas correlacionadas o subselecciones. Hasta la versión 5.6.5, no materializa subconsultas, sin embargo, materializa una tabla derivada utilizada en una combinación.

En esencia, esto significa que cuando usa una combinación, la primera vez que se encuentra la subconsulta, MySQL realizará lo siguiente:

SELECT code1 FROM myTable GROUP BY code1 HAVING COUNT(code1) > 1

Y mantenga los resultados en una tabla temporal (a la que se le asigna un hash para que las búsquedas sean más rápidas), luego para cada valor en myTable buscará en la tabla temporal para ver si el código está allí.

Sin embargo, desde que usas IN la subconsulta no se materializa y se reescribe como:

SELECT t1.code1, t1.code2
FROM myTable t1
WHERE EXISTS
    (   SELECT t2.code1 
        FROM myTable t2
        WHERE t2.Code1 = t1.Code1
        GROUP BY t2.code1 
        HAVING COUNT(t2.code1) > 1
    )

Lo que significa que para cada code en myTable , vuelve a ejecutar la subconsulta. Que cuando su consulta externa es muy estrecha está bien, ya que es más eficiente ejecutar la subconsulta solo unas pocas veces, que ejecutarla para todos los valores y almacenar los resultados en una tabla temporal, sin embargo, cuando su consulta externa es amplia, resulta en la consulta interna ejecutándose muchas veces, y aquí es donde entra en juego la diferencia de rendimiento.

Entonces, para el recuento de filas, en lugar de ejecutar la subconsulta unas 30 000 veces, la ejecuta una vez, luego busca unas 30 000 filas en una tabla temporal con hash con solo 400 filas. Esto representaría una diferencia de rendimiento tan drástica.

Este artículo en la documentación en línea explica la optimización de subconsultas con mucha más profundidad.