Selon le chapitre 9 (analyseur et optimiseur), page 172 du livre Comprendre les composants internes de MySQL par Sasha Pachev
voici la répartition de l'évaluation d'une requête selon les tâches suivantes:
- Déterminez quelles clés peuvent être utilisées pour récupérer les enregistrements des tables et choisissez la meilleure pour chaque table.
- Pour chaque table, décidez si une analyse de table est meilleure que la lecture sur une clé. S'il y a beaucoup d'enregistrements qui correspondent à la valeur de la clé, les avantages de la clé sont réduits et l'analyse de la table devient plus rapide.
- Déterminez l'ordre dans lequel les tables doivent être jointes lorsque plusieurs tables sont présentes dans la requête.
- Réécrivez les clauses WHERE pour éliminer le code mort, en réduisant les calculs inutiles et en changeant les contraintes autant que possible pour ouvrir la voie à l'utilisation des clés.
- Éliminez les tables inutilisées de la jointure.
- Déterminez si les clés peuvent être utilisées pour
ORDER BY
et GROUP BY
.
- Essayez de simplifier les sous-requêtes et déterminez dans quelle mesure leurs résultats peuvent être mis en cache.
- Fusionner les vues (développer la référence de vue en tant que macro)
Sur cette même page, il dit ce qui suit:
Dans la terminologie de l'optimiseur MySQL, chaque requête est un ensemble de jointures. Le terme jointure est utilisé ici plus largement que dans les commandes SQL. Une requête sur une seule table est une jointure dégénérée. Bien que nous ne pensions normalement pas lire les enregistrements d'une table comme une jointure, les mêmes structures et algorithmes utilisés avec les jointures conventionnelles fonctionnent parfaitement pour résoudre la requête avec une seule table.
ÉPILOGUE
En raison des clés présentes, de la quantité de données et de l'expression de la requête, les jointures MySQL peuvent parfois faire des choses pour notre propre bien (ou pour nous revenir) et produire des résultats que nous ne nous attendions pas et ne pouvons pas expliquer rapidement.
J'ai écrit sur cette bizarrerie avant
parce que MySQL Query Optimizer pourrait faire ignorer certaines clés lors de l'évaluation de la requête.
Le commentaire de @ Phil m'aide à voir comment publier cette réponse (+1 pour le commentaire de @ Phil)
Le commentaire de @ ypercube (+1 pour celui-ci aussi) est une version compacte de mon article car l'optimiseur de requêtes de MySQL est primitif. Malheureusement, cela doit être le cas puisqu'il s'agit de moteurs de stockage extérieurs.
CONCLUSION
En ce qui concerne votre question réelle, l'optimiseur de requêtes MySQL déterminerait les mesures de performances de chaque requête lorsqu'elle sera effectuée
- compter les lignes
- sélection des clés
- masser les jeux de résultats intermittents
- Oh ouais, faire le REJOINDRE réel
Vous devrez probablement contraindre l'ordre d'exécution en réécrivant (refactorisant) la requête
Voici la première requête que vous avez donnée
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Essayez de le réécrire pour évaluer le WHERE en premier
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Cela modifierait certainement le plan EXPLAIN. Cela pourrait produire des résultats meilleurs ou pires.
J'ai déjà répondu à une question dans StackOverflow où j'ai appliqué cette technique. L'EXPLAIN était horrible mais la performance était de la dynamite. Cela n'a fonctionné qu'en raison de la présence des index corrects et de l'utilisation de LIMIT dans une sous-requête .
Comme pour les cours des actions, lorsqu'il s'agit de requêtes et d'essayer de les exprimer, des restrictions s'appliquent, les résultats peuvent varier et les performances passées ne sont pas indicatives des résultats futurs.