PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Expliquer JOIN vs. LEFT JOIN et WHERE suggestion de performance de condition plus en détail

En effet, WHERE conditions et JOIN conditions pour [INNER] JOIN sont 100 % équivalents dans PostgreSQL. (C'est une bonne pratique d'utiliser un JOIN explicite conditions pour faciliter la lecture et la maintenance des requêtes).

La même chose n'est pas true pour une LEFT JOIN combiné avec un WHERE condition sur une table à droite de la jointure. Le but d'un LEFT JOIN est de conserver toutes les lignes du côté gauche de la jointure, quelle que soit la correspondance du côté droit. Si aucune correspondance n'est trouvée, la ligne est étendue avec NULL valeurs pour les colonnes du côté droit. Le manuel :

LEFT OUTER JOIN

Tout d'abord, une jointure interne est effectuée. Ensuite, pour chaque ligne de T1 qui ne satisfait pas la condition de jointure avec une ligne de T2, une ligne jointe est ajoutée avec des valeurs nulles dans les colonnes de T2. Ainsi, le tableau joint a toujours au moins une ligne pour chaque ligne dans T1.

Si vous appliquez ensuite un WHERE condition qui nécessite autre chose qu'un NULL value sur les colonnes des tables du côté droit, vous annulez l'effet et convertissez de force le LEFT [OUTER] JOIN pour fonctionner comme un simple [INNER] JOIN , juste (peut-être) plus cher en raison d'un plan de requête plus compliqué.

Dans une requête avec de nombreuses tables jointes, Postgres (ou n'importe quel SGBDR) a du mal à trouver le meilleur (ou même un bon) plan de requête. Le nombre de séquences théoriquement possibles pour joindre des tables augmente factoriellement (!). Postgres utilise "l'optimiseur de requête générique" pour la tâche et certains paramètres l'influencent.

Obfusquer la requête avec un LEFT JOIN trompeur comme indiqué, rend le travail du planificateur de requêtes plus difficile, est trompeur pour les lecteurs humains et indique généralement des erreurs dans la logique de requête.

Réponses associées aux problèmes qui en découlent :

  • Pourquoi null est-il égal à entier dans WHERE ?
  • Requête avec LEFT JOIN ne renvoyant pas de lignes pour un nombre de 0
  • Requête SQL utilisant une jointure externe et limitant les enregistrements enfants pour chaque parent
  • Jointure externe gauche agissant comme une jointure interne
  • Sélectionnez les lignes qui ne sont pas présentes dans un autre tableau

Etc.