Der PostgreSQL-Abfrageplaner ist intelligent, aber keine KI. Verwenden Sie dazu einen Index für einen Ausdruck Verwenden Sie genau die gleiche Ausdrucksform in der Abfrage.
Mit einem Index wie diesem:
CREATE INDEX t_a_lower_idx ON t (lower(substring(a, 1, 4)));
Oder einfacher in PostgreSQL 9.1:
CREATE INDEX t_a_lower_idx ON t (lower(left(a, 4)));
Verwenden Sie diese Abfrage:
SELECT * FROM t WHERE lower(left(a, 4)) = 'abcd';
Was zu 100 % funktionell gleichwertig ist mit:
SELECT * FROM t WHERE lower(a) LIKE 'abcd%'
Oder:
SELECT * FROM t WHERE a ILIKE 'abcd%'
Aber nicht :
SELECT * FROM t WHERE a LIKE 'abcd%'
Dies ist eine funktional andere Abfrage und Sie brauchen eine andere index:
CREATE INDEX t_a_idx ON t (substring(a, 1, 4));
Oder einfacher mit PostgreSQL 9.1:
CREATE INDEX t_a_idx ON t (left(a, 4));
Und verwenden Sie diese Abfrage:
SELECT * FROM t WHERE left(a, 4) = 'abcd';
Links verankerte Suchbegriffe variabler Länge
Groß- und Kleinschreibung wird nicht beachtet. Inhaltsverzeichnis:
Bearbeiten :Fast vergessen:Wenn Sie Ihre Datenbank mit einem anderen Gebietsschema als dem Standard-'C' ausführen, müssen Sie Operatorklasse explizit angeben
- text_pattern_ops
in meinem Beispiel:
CREATE INDEX t_a_lower_idx
ON t (lower(left(a, <insert_max_length>)) text_pattern_ops);
Abfrage:
SELECT * FROM t WHERE lower(left(a, <insert_max_length>)) ~~ 'abcdef%';
Kann den Index nutzen und ist fast so schnell wie die Variante mit fester Länge.
Dieser Beitrag auf dba.SE mit weiteren Details zum Musterabgleich
könnte Sie interessieren , insbesondere der letzte Teil über die Operatoren ~>=~
und ~<~
.