PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL verwendet keinen partiellen Index

Ein teilweiser Index ist eine gute Idee um die Hälfte der Zeilen der Tabelle auszuschließen, die Sie offensichtlich nicht benötigen. Einfacher:

CREATE INDEX name_idx ON table (text_col)
WHERE text_col IS NOT NULL;

Stellen Sie sicher, dass Sie ANALYZE table ausführen nach Erstellung des Indexes. (Autovacuum macht das nach einiger Zeit automatisch, wenn Sie es nicht manuell tun, aber wenn Sie direkt nach der Erstellung testen, wird Ihr Test fehlschlagen.)

Wiederholen Sie dann WHERE, um den Abfrageplaner davon zu überzeugen, dass ein bestimmter Teilindex verwendet werden kann Bedingung in der Abfrage - auch wenn es völlig überflüssig erscheint:

SELECT col1,col2, .. colN
FROM   table 
WHERE  text_col = 'my_value'
AND   text_col IS NOT NULL;  -- repeat condition

Voilá.

Per Dokumentation:

Beachten Sie jedoch, dass das Prädikat mit den Bedingungen übereinstimmen muss, die in den Abfragen verwendet werden, die vom Index profitieren sollen. Genauer gesagt kann ein partieller Index nur dann in einer Abfrage verwendet werden, wenn das System erkennen kann, dass das WHERE ist Bedingung der Abfrage impliziert mathematisch das Prädikat des Index. PostgreSQL hat keinen ausgeklügelten Theorem-Beweiser, der mathematisch äquivalente Ausdrücke erkennen kann, die in unterschiedlichen Formen geschrieben sind. (Ein solcher allgemeiner Theorem-Beweis ist nicht nur extrem schwierig zu erstellen, er wäre wahrscheinlich auch zu langsam, um von wirklichem Nutzen zu sein.) Das System kann einfache Implikationen von Ungleichungen erkennen, z. B. "x <1" impliziert "x <2"; andernfalls das Prädikat Bedingung muss genau mit einem Teil des WHERE der Abfrage übereinstimmen Bedingung oder der Index wird nicht als verwendbar erkannt. Der Abgleich erfolgt zur Planungszeit der Abfrage, nicht zur Laufzeit. Als Ergebnis funktionieren parametrisierte Abfrageklauseln nicht mit einem Teilindex.

Wie bei parametrisierten Abfragen:Fügen Sie wieder das (redundante) Prädikat des Teilindex als zusätzliche Konstante WHERE hinzu Zustand, und es funktioniert einwandfrei.

Ein wichtiges Update in Postgres 9.6 verbessert die Chancen für Nur-Index-Scans erheblich (was Abfragen billiger machen kann und der Abfrageplaner solche Abfragepläne leichter auswählt). Verwandte:

  • PostgreSQL verwendet keinen Index während der Zählung(*)