| Documentation PostgreSQL 7.2 | ||
|---|---|---|
| <<< Previous | Astuces de performance | Next >>> |
Depuis PostgreSQL 7.1 il est possible de contrôler le planner de requête pour certaines extensions en utilisant la syntaxe explicite JOIN.
Une simple jointure de requête comme :
SELECT * FROM a,b,c WHERE a.id = b.id AND b.ref = c.id;
|
Quand un plan de requête comprend deux ou trois tables, il n'y a pas à chercher plusieurs ordonnancements de jointures. Mais le nombre d'ordonnancements de jointures croît exponentiellement par rapport au nombre de tables. À partir de 10 tables il n'est pas pratique de faire une recherche exhaustive de toutes les possibilités, et même pour six ou sept tables le planning peut prendre beaucoup de temps. Quand il y a trop d'entrées tables, le planner de PostgreSQL permutera d'une recherche exhaustive en une recherche probabiliste génétique à travers un nombre de possibilités limitées. (Le seuil de permutation est est placé par le paramètre de lancement GEQO_THRESHOLD décrit dans le Guide de l'administrateur). La recherche génétique prend moins de temps, mais ne trouvera pas nécessairement le meilleur plan de requête possible.
Quand la requête comprend des jointures externes, le planner a moins de liberté que pour les jointures internes (pleines). Par exemple,
SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
|
Depuis PostgreSQL 7.1, le planner traite toutes les syntaxes explicites JOIN comme contraignant l'ordonnancement de jointure, même si ce n'est pas logiquement nécessaire pour faire une contrainte pour des jointures internes. Donc, bien que toutes ces requêtes donnent le même résultat :
SELECT * FROM a,b,c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
|
Vous n'avez pas besoin de contraindre l'ordonnancement de jointure complètement afin de réduire le temps de recherche, car utiliser les opérateurs de jointure fonctionne dans une liste FROM. Par exemple,
SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
|
Si vous avez un mélange de jointures internes et externes dans une requête complexe, vous pouvez ne pas vouloir contraindre la recherche du planner pour un bon ordonnancement de jointures internes dans une jointure externe. Vous ne pouvez faire ceci directement dans la syntaxe JOIN, mais pouvez obtenir une limitation syntaxique en utilisant les sous sélections. Par exemple,
SELECT * FROM d LEFT JOIN
(SELECT * FROM a, b, c WHERE ...) AS ss
ON (...);
|
Contraindre la recherche du planner de cette façon est techniquement pratique pour réduire le temps de planning et pour diriger le planner vers un bon plan de requête. Si le planner choisi un mauvais ordonnancement de jointure par défaut, vous pouvez le forcer à choisir un meilleur ordonnancement par la syntaxe JOIN --- en supposant que vous connaissez un meilleur ordonnancement. L'expérimentation est recommandée.
| <<< Previous | Home | Next >>> |
| Statistiques utilisées par le planner | Up | Remplir une base |