Mysql
 sql >> Base de données >  >> RDS >> Mysql

JOIN vs. WHERE :pourquoi deux requêtes qui obtiennent des résultats identiques présentent-elles une différence de performances de 3 à 4 ordres de grandeur ?

MySQL a problèmes connus avec des requêtes d'optimisation impliquant des sous-requêtes corrélées ou des sous-sélections. Jusqu'à la version 5.6.5, il ne matérialise pas les sous-requêtes, mais il matérialisera une table dérivée utilisée dans une jointure.

Cela signifie essentiellement que lorsque vous utilisez une jointure, la première fois que la sous-requête est rencontrée, MySQL effectuera les actions suivantes :

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

Et conservez les résultats dans une table temporaire (qui est hachée pour accélérer les recherches), puis pour chaque valeur dans myTable il recherchera dans la table temporaire pour voir si le code s'y trouve.

Cependant, depuis quand vous utilisez IN la sous-requête n'est pas matérialisée et est réécrite comme :

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
    )

Ce qui signifie que pour chaque code dans myTable , il exécute à nouveau la sous-requête. Ce qui convient lorsque votre requête externe est très étroite, car il est plus efficace de n'exécuter la sous-requête que quelques fois, que de l'exécuter pour toutes les valeurs et de stocker les résultats dans une table temporaire, mais lorsque votre requête externe est large, il en résulte dans la requête interne s'exécutant plusieurs fois, et c'est là que la différence de performances entre en jeu.

Ainsi, pour le nombre de lignes, au lieu d'exécuter la sous-requête environ 30 000 fois, vous l'exécutez une fois, puis recherchez environ 30 000 lignes dans une table temporaire hachée contenant seulement 400 lignes. Cela représenterait une différence de performances drastique.

Cet article dans la documentation en ligne explique l'optimisation des sous-requêtes de manière beaucoup plus approfondie.