PostgreSQL-forespørgselsplanlæggeren er smart, men ikke en AI. For at få det til at bruge et indeks på et udtryk bruge den nøjagtig samme udtryksform i forespørgslen.
Med et indeks som dette:
CREATE INDEX t_a_lower_idx ON t (lower(substring(a, 1, 4)));
Eller enklere i PostgreSQL 9.1:
CREATE INDEX t_a_lower_idx ON t (lower(left(a, 4)));
Brug denne forespørgsel:
SELECT * FROM t WHERE lower(left(a, 4)) = 'abcd';
Hvilket 100 % funktionelt svarer til:
SELECT * FROM t WHERE lower(a) LIKE 'abcd%'
Eller:
SELECT * FROM t WHERE a ILIKE 'abcd%'
Men ikke :
SELECT * FROM t WHERE a LIKE 'abcd%'
Dette er en funktionelt anden forespørgsel og du har brug for en anden indeks:
CREATE INDEX t_a_idx ON t (substring(a, 1, 4));
Eller enklere med PostgreSQL 9.1:
CREATE INDEX t_a_idx ON t (left(a, 4));
Og brug denne forespørgsel:
SELECT * FROM t WHERE left(a, 4) = 'abcd';
Venstre forankrede søgetermer af variabel længde
Ufølsom mellem store og små bogstaver. Indeks:
Rediger :Næsten glemt:Hvis du kører din db med en anden lokalitet end standard 'C', skal du angiv operatorklassen eksplicit
- text_pattern_ops
i mit eksempel:
CREATE INDEX t_a_lower_idx
ON t (lower(left(a, <insert_max_length>)) text_pattern_ops);
Forespørgsel:
SELECT * FROM t WHERE lower(left(a, <insert_max_length>)) ~~ 'abcdef%';
Kan udnytte indekset og er næsten lige så hurtig som varianten med en fast længde.
Du kan være interesseret i dette indlæg på dba.SE med flere detaljer om mønstermatchning
, især den sidste del om operatorerne ~>=~
og ~<~
.