SelfTest: Geschwindigkeitssteigerung durch »NOT EXISTS« anstelle von »NOT IN«
Nicht ganz frische PostgreSQL-Versionen (mindestens bis 9.6 inklusive)
optimieren »NOT IN«-mit-Subquery nicht automatisch und müssen daher
für jede Zeile des äußeren Selects einen linearen Scan auf die
Subquery-Tabelle machen.
Deutlich effektiver ist das in diesem Fall äquivalente »NOT
EXISTS«-mit-Subquery.
Beispiel: Namen aller Kunden, für die noch keine Rechnung geschrieben
wurde. Falsch mit »NOT IN«:
SELECT name
FROM customer
WHERE id NOT IN (
SELECT customer_id
FROM ar
);
Besser und semantisch äquivalent:
SELECT name
FROM customer
WHERE NOT EXISTS (
SELECT customer_id
FROM ar
WHERE customer_id = customer.id
);
Geschwindigkeitssteigerung ist auch ein Euphemismus. Vor der Änderung
war der Selftest bei der LINET-Produktivdatenbank nicht in der Lage,
seine Tests innerhalb von drei Tagen auszuführen. Nach der Änderung
dauert der Selftest weniger als eine Minute.
Neure PostgreSQL-Versionen (z.B. v11) erkennen dieses Pattern
automatisch.