web-dev-qa-db-fra.com

UTILISER la construction dans la clause JOIN peut introduire des barrières d'optimisation dans certains cas?

Il a été porté à mon attention que la construction USING (au lieu de ON) dans la clause FROM des requêtes SELECT pourrait introduire des barrières d'optimisation dans certains cas.

Je veux dire ce mot clé:

 CHOISIR * 
 À PARTIR d'un 
 JOINDRE b EN UTILISANT (aide)

Juste dans des cas plus complexes.

Contexte: ce commentaire à cette question .

J'utilise ceci beaucoup et je n'ai encore rien remarqué jusqu'à présent. Je serais très intéressé par un cas de test démontrant l'effet ou tout lien pour plus d'informations. Mes efforts de recherche sont vides.

La réponse parfaite serait un cas de test pour montrer USING (a_id) avec des performances inférieures par rapport à la clause de jointure alternative ON a.a_id = b.a_id - si cela peut réellement arriver.

36
Erwin Brandstetter

Erwin: Je serais d'accord avec l'idée que l'utilisation de provoquer une commande rigide pourrait bien créer de nombreux cas Edge où des plans optimaux seraient exclus. J'ai récemment aidé quelqu'un qui avait quelque chose comme ça dans sa requête:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

Dans son cas, le pire de ces blocs de jointure provoquait une jointure en boucle imbriquée sur quelque 200 000 lignes, environ 20 000 fois (faites le calcul), et comme les clés ne pouvaient pas être poussées vers les index, il s'agissait d'un balayage séquentiel. Cela signifie que la requête globale a pris environ 3 heures à s'exécuter en raison des modifications du plan en cascade. En distribuant la jointure gauche, les clés peuvent être enfoncées et la requête s'exécute en quelques secondes. Bien sûr, ce n'est pas exactement équivalent, c'est pourquoi le planificateur ne peut pas les traiter comme équivalents et il a donc été laissé de comprendre ce plan comme une jointure de hachage, puis de faire une boucle imbriquée, ce qui était douloureusement lent.

Chaque fois que vous forcez rigoureusement les jointures à passer dans un certain ordre, vous introduisez des cas où les informations de filtrage clés peuvent ne pas encore être disponibles dans l'exécution du plan, et donc ce qui pourrait être possible plus tard dans une analyse rapide d'index/jointure de hachage il peut être nécessaire de faire beaucoup plus lentement dans une boucle imbriquée/balayage séquentiel et donc bien que le fragment ci-dessus ne soit pas immédiatement équivalent, il présente le même problème.

12
Chris Travers