sql >> Database >  >> RDS >> PostgreSQL

Leg JOIN vs. LEFT JOIN en WHERE conditie prestatiesuggestie in meer detail uit

Effectief, WHERE voorwaarden en JOIN voorwaarden voor [INNER] JOIN zijn 100 % equivalent in PostgreSQL. (Het is een goede gewoonte om expliciete JOIN te gebruiken voorwaarden om zoekopdrachten gemakkelijker te lezen en te onderhouden).

Hetzelfde is niet waar voor een LEFT JOIN gecombineerd met een WHERE voorwaarde op een tafel rechts van de join. Het doel van een LEFT JOIN is om alle rijen aan de linkerkant van de join te behouden, ongeacht een match aan de rechterkant. Als er geen overeenkomst wordt gevonden, wordt de rij uitgebreid met NULL waarden voor kolommen aan de rechterkant. De handleiding:

LEFT OUTER JOIN

Eerst wordt een inner join uitgevoerd. Vervolgens wordt voor elke rij in T1 die niet voldoet aan de join-voorwaarde met een rij in T2, een samengevoegde rij toegevoegd met null-waarden in kolommen van T2. De samengevoegde tabel heeft dus altijd ten minste één rij voor elke rij in T1.

Als u vervolgens een WHERE . toepast voorwaarde die iets anders vereist dan een NULL waarde op kolommen met tabellen aan de rechterkant, maakt u het effect ongeldig en zet u de LEFT [OUTER] JOIN met geweld om om te werken als een eenvoudige [INNER] JOIN , alleen (mogelijk) duurder vanwege een ingewikkelder zoekplan.

In een query met veel samengevoegde tabellen, is het voor Postgres (of een RDBMS) moeilijk om het beste (of zelfs een goede) queryplan te vinden. Het aantal theoretisch mogelijke reeksen om tabellen samen te voegen groeit factorieel (!). Postgres gebruikt de "Generic Query Optimizer" voor de taak en er zijn enkele instellingen om deze te beïnvloeden.

De zoekopdracht verdoezelen met misleidende LEFT JOIN zoals uiteengezet, maakt het werk van de queryplanner moeilijker, is misleidend voor menselijke lezers en duidt meestal op fouten in de querylogica.

Gerelateerde antwoorden voor problemen die hieruit voortkomen:

  • Waarom is null gelijk aan geheel getal in WHERE?
  • Query met LEFT JOIN retourneert geen rijen voor telling van 0
  • SQL-query met behulp van outer join en beperking van onderliggende records voor elke ouder
  • Linker buitenste join gedraagt ​​zich als inner join
  • Selecteer rijen die niet aanwezig zijn in een andere tabel

enz.



  1. MySQL:transactie binnen een opgeslagen procedure

  2. Hoe u consequent een Microsoft Access MVP Award kunt verdienen

  3. COUNT(*) selecteren met DISTINCT

  4. Hoe DATE en TIME te scheiden van DATETIME in MySQL