53 votes

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

J'ai le texte suivant requête MySql:

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

Il faut environ 30 secondes pour s'exécuter, ce qui est étrange, parce que si je commente les rejoindre ou à la clause where, il faut moins d'une seconde: c'est à dire

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 ya la STRAIGHT_JOIN mot-clé, qui je peut trouver une référence, ici: http://dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN est similaire à la REJOINDRE, sauf que la table de gauche est toujours lire avant de la table de droite. Cela peut être utilisé pour ceux (rares) cas de qui l'optimiseur de jointure met l' tables dans le mauvais ordre.

Quoi? 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.

Encore 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 il prend moins d'une seconde, et cette syntaxe ne semble pas encore être juridique.

Je suppose que le deuxième exemple signifie qu'un STRAIGHT_JOIN sera utilisé chaque fois qu'une JOINTURE INTERNE est écrit, mais je ne trouve pas de documentation à ce sujet.

Ce qui se passe ici, et comment les "optimiseur de jointure" suite à ces résultats relativement médiocres? Dois-je toujours utiliser STRAIGHT_JOIN? Comment puis-je savoir quand l'utiliser ou pas?

Table1 et Table2 les deux ont entier clés primaires; FilterID est une clé étrangère dans une autre table; le CommonID les colonnes sont les deux clés étrangères d'une troisième table. Ils ont tous les deux index sur eux. Le moteur de base de données InnoDB.

Merci

43voto

Quassnoi Points 191041

Ce qui se passe ici, et comment les "optimiseur de jointure" suite à ces résultats relativement médiocres?

STRAIGHT_JOIN des forces de l'ordre de jointure des tables, alors table1 est analysé dans la boucle externe et table2 dans la boucle interne.

L'optimiseur n'est pas parfait (mais stil assez décent), et la cause la plus probable est les statistiques obsolètes.

Dois-je toujours utiliser STRAIGHT_JOIN

Non, seulement quand l'optimiseur est faux. Cela peut être si votre distribution de données est fortement biaisée ou ne peut pas être calculée correctement (par exemple, pour l'espace ou fulltext index).

Comment puis-je savoir quand l'utiliser ou pas?

Vous devez collecter les statistiques, de construire les plans pour les deux sens et de comprendre ce que font ces plans de moyenne.

Si vous voyez que:

  1. L'généré automatiquement le plan n'est pas optimale et ne peut pas être amélioré par les moyens habituels,

  2. L' STRAIGHT_JOIN version est mieux, vous comprenez qu'il sera pour toujours et à comprendre pourquoi elle le restera toujours

, puis utilisez STRAIGHT_JOIN.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X