Die Verwirrung um LEFT JOIN
und WHERE
Klausel wurde mehrfach verdeutlicht:
Diese interessante Frage bleibt:
Es gibt keine expliziten Abfragehinweise in Postgres. (Dies ist eine Frage der laufenden Debatte.) Aber es gibt immer noch verschiedene Tricks, um Postgres dazu zu bringen, sich Ihren Weg zu bahnen.
Aber fragen Sie sich zuerst: Warum hat der Abfrageplaner den ausgewählten Plan von vornherein als günstiger eingeschätzt? Ist Ihre Serverkonfiguration grundsätzlich in Ordnung? Kosteneinstellungen ausreichend? autovacuum
laufend? Postgres-Version veraltet? Umgehen Sie ein zugrunde liegendes Problem, das wirklich behoben werden sollte?
Wenn Sie Postgres zwingen, es auf Ihre Weise zu tun, sollten Sie sicher sein, dass es nach einem Versions-Upgrade oder Update der Serverkonfiguration nicht zurückfeuert ... Sie sollten besser wissen, was Sie genau tun.
Das heißt, Sie können zwingen Sie Postgres dazu, "einige Datensätze herauszufiltern, bevor Sie JOIN
ausführen " mit einer Unterabfrage, in der Sie OFFSET 0
hinzufügen - was logischerweise nur Rauschen ist, aber Postgres daran hindert, es in Form eines regulären Joins neu anzuordnen. (Immerhin Abfragehinweis)
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;
Oder Sie können einen CTE verwenden (weniger obskur, aber teurer). Oder andere Tricks wie das Setzen bestimmter Konfigurationsparameter. Oder in diesem speziellen Fall würde ich einen LATERAL
verwenden Join mit dem gleichen 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;
Verwandte:
Hier ist ein ausführlicher Blog zu Abfragehinweisen von 2ndQuadrant. Fünf Jahre alt, aber noch gültig.