sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL:Brug af AND-sætning i LEFT JOIN fungerer ikke som forventet

Forvirringen omkring LEFT JOIN og WHERE klausul er blevet præciseret mange gange:

Dette interessante spørgsmål forbliver:

Der er ingen eksplicitte forespørgselstip i Postgres. (Hvilket er et spørgsmål om løbende debat.) Men der er stadig forskellige tricks til at få Postgres til at bøje sig.

Men spørg først dig selv: Hvorfor vurderede forespørgselsplanlæggeren, at den valgte plan var billigere til at begynde med? Er din serverkonfiguration grundlæggende fornuftig? Omkostningsindstillinger tilstrækkelige? autovacuum løber? Postgres version forældet? Arbejder du omkring et underliggende problem, som virkelig burde løses?

Hvis du tvinger Postgres til at gøre det på din måde, skal du være sikker på, at det ikke starter igen, efter en versionsopgradering eller opdatering til serverkonfigurationen... Du må hellere vide, hvad du præcist gør.

Når det er sagt, du kan tving Postgres til at "filtrere nogle poster, før du udfører JOIN " med en underforespørgsel, hvor du tilføjer OFFSET 0 - hvilket bare er støj, logisk set, men forhindrer Postgres i at omarrangere det i form af en almindelig join. (Forespørgselstip trods alt)

SELECT la.listing_id, la.id, lar.*
FROM  (
   SELECT listing_id, id
   FROM   la
   WHERE  listing_id = 2780
   OFFSET 0
   ) la
LEFT   JOIN lar  ON lar.application_id = la.id;

Eller du kan bruge en CTE (mindre obskur, men dyrere). Eller andre tricks som at indstille bestemte konfigurationsparametre. Eller, i dette særlige tilfælde, vil jeg bruge en LATERAL slutte sig til samme effekt:

SELECT la.listing_id, la.id, lar.*
FROM   la
LEFT  JOIN LATERAL (
   SELECT *
   FROM   lar
   WHERE  application_id = la.id
   )  lar ON true
WHERE  la.listing_id = 2780;

Relateret:

Her er en omfattende blog om Query hints by 2ndQuadrant. Fem år gammel, men stadig gyldig.



  1. Oracle BI Publisher - Sådan formateres tal som tekst, så indledende nuller ikke forsvinder

  2. SQL Server svarende til Oracles CREATE OR REPLACE VIEW

  3. Samlet funktion i MySQL - liste (som LISTAGG i Oracle)

  4. Hvad er den bedste måde at opnå hurtige indsættelser af store mængder data i MySQL?