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.