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

Auswirkungen auf die Leistung von leerem LIKE in einer vorbereiteten Anweisung

Postgres 9.2 oder höher ist im Allgemeinen schlau genug, um zu erkennen, dass die Bedingung

WHERE name LIKE '%%'

ist nicht selektiv und greift auf einen sequentiellen Scan zurück, der den GiST-Index ignoriert - auch bei vorbereiteten Anweisungen. Sie tun einen kleinen Preis für den unbrauchbaren Zustand bezahlen.

In Postgres 9.1 oder früher würde ich eine separate Abfrage für den Sonderfall erstellen.

Vergleichen Sie die Notizen Abschnitt für PREPARE Anweisung im Handbuch für die Versionen 9.1 , 9.2 und 9.3 .

Bestätigen Sie sich selbst

Bereiten Sie die Anweisung vor und führen Sie EXPLAIN ANALYZE aus zum Testen:

PREPARE plan1 (text) AS
SELECT  * FROM file
WHERE   name LIKE $1;

EXPLAIN ANALYZE EXECUTE plan1('%123%');

EXPLAIN ANALYZE EXECUTE plan1('%%');

Pläne werden im Allgemeinen für die Dauer der Sitzung zwischengespeichert.

Alternative Abfrage

Unabhängig von der Version, die Sie ausführen, sollte diese Abfrage bei einer vorbereiteten Anweisung schneller sein, wenn Sie immer eine Volltextsuche durchführen (Platzhalter links und rechts):

SELECT * FROM files WHERE name LIKE ('%' || $1 || '%');

Und übergeben Sie das Muster ohne hinzugefügte Platzhalter (% ), Natürlich. Auf diese Weise weiß Postgres, dass es zur Planungszeit ein Muster erwartet, das in Platzhalter eingeschlossen ist.

->SQLfiddle-Demo.
Beachten Sie den sequentiellen Scan für das leere LIKE und den Leistungsunterschied zwischen den beiden Plänen.
SQLfiddle variiert stark, je nach Auslastung usw. Ein einzelner Lauf ist möglicherweise nicht zuverlässig. Testen Sie besser in Ihrer Umgebung und führen Sie jede Anweisung ein paar Mal aus, um den Cache zu sättigen und Rauschen zu eliminieren.