Pourquoi STRAIGHT_JOIN améliore-t-il si radicalement cette requête et que signifie-t-il lorsqu’il est écrit après le mot-clé SELECT?

J’ai la requête MySql suivante:

select t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1 

Cela prend environ 30 secondes pour exécuter, ce qui était étrange, car si je commente la jointure ou la clause where cela prend moins d’une seconde:

 select t1.* from Table1 t1 where t1.FilterID = 1 

ou

 select t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID 

chacun prend moins d’une seconde.

Ensuite, il y a le mot-clé STRAIGHT_JOIN, dont je peux trouver une référence ici: http://dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN est similaire à JOIN, sauf que la table de gauche est toujours lue avant la table de droite. Cela peut être utilisé pour les (rares) cas pour lesquels l’optimiseur de jointure place les tables dans le mauvais ordre.

Quelle? Je peux écrire:

 select t1.* from Table1 t1 STRAIGHT_JOIN Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1 

et la requête s’exécute en moins d’une seconde.

Même plus étrange, je peux écrire:

 select STRAIGHT_JOIN t1.* from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1 

et cela prend moins d’une seconde, et cette syntaxe ne semble même pas être légale.

Je suppose que le deuxième exemple signifie qu’un STRAIGHT_JOIN sera utilisé chaque fois qu’un INNER JOIN est écrit, mais je ne trouve aucune documentation à ce sujet.

Que se passe-t-il ici, et comment «l’optimiseur de jointure» peut-il entraîner une performance relativement médiocre? Dois-je toujours utiliser STRAIGHT_JOIN? Comment puis-je savoir quand l’utiliser ou non?

Table1 et Table2 ont toutes deux des clés primaires entières; FilterID est une clé étrangère à une autre table; les colonnes CommonID ​​sont toutes deux des clés étrangères à une troisième table. Ils ont tous les deux des index sur eux. Le moteur de firebase database est InnoDB.

Merci

Que se passe-t-il ici, et comment «l’optimiseur de jointure» peut-il entraîner une performance relativement médiocre?

STRAIGHT_JOIN force l’ordre de jointure des tables, de sorte que table1 est analysée dans la boucle externe et table2 dans la boucle interne.

L’optimiseur n’est pas parfait (bien que tout à fait décent), et la cause la plus probable est les statistiques obsolètes.

Devrais-je toujours utiliser STRAIGHT_JOIN

Non, seulement lorsque l’optimiseur a tort. Cela peut être le cas si votre dissortingbution de données est gravement biaisée ou ne peut pas être calculée correctement (par exemple, pour les index spatiaux ou complets).

Comment puis-je savoir quand l’utiliser ou non?

Vous devez collecter les statistiques, créer des plans pour les deux sens et comprendre ce que signifient ces plans.

Si vous voyez cela:

  1. Le plan généré automatiquement n’est pas optimal et ne peut pas être amélioré par les moyens standard,

  2. La version STRAIGHT_JOIN est meilleure, vous comprenez qu’elle le fera toujours et comprendra pourquoi elle le fera toujours

, puis utilisez STRAIGHT_JOIN .