Planer zapytań PostgreSQL jest sprytny, ale nie jest sztuczną inteligencją. Aby użyć indeksu wyrażenia użyj dokładnie tej samej formy wyrażenia w zapytaniu.
Z indeksem takim jak ten:
CREATE INDEX t_a_lower_idx ON t (lower(substring(a, 1, 4)));
Lub prościej w PostgreSQL 9.1:
CREATE INDEX t_a_lower_idx ON t (lower(left(a, 4)));
Użyj tego zapytania:
SELECT * FROM t WHERE lower(left(a, 4)) = 'abcd';
Co jest w 100% funkcjonalnym odpowiednikiem:
SELECT * FROM t WHERE lower(a) LIKE 'abcd%'
Lub:
SELECT * FROM t WHERE a ILIKE 'abcd%'
Ale nie :
SELECT * FROM t WHERE a LIKE 'abcd%'
To jest funkcjonalnie inne zapytanie i potrzebujesz innego indeks:
CREATE INDEX t_a_idx ON t (substring(a, 1, 4));
Lub prościej z PostgreSQL 9.1:
CREATE INDEX t_a_idx ON t (left(a, 4));
I użyj tego zapytania:
SELECT * FROM t WHERE left(a, 4) = 'abcd';
Wyszukiwane hasła zakotwiczone z lewej strony o zmiennej długości
Wielkość liter nie jest wrażliwa. Indeks:
Edytuj :Prawie zapomniałeś:Jeśli uruchamiasz swoją bazę danych z innymi ustawieniami regionalnymi niż domyślny 'C', musisz określ wyraźnie klasę operatora
- text_pattern_ops
w moim przykładzie:
CREATE INDEX t_a_lower_idx
ON t (lower(left(a, <insert_max_length>)) text_pattern_ops);
Zapytanie:
SELECT * FROM t WHERE lower(left(a, <insert_max_length>)) ~~ 'abcdef%';
Może wykorzystywać indeks i jest prawie tak szybki jak wariant o stałej długości.
Być może zainteresuje Cię ten post na dba.SE zawierający więcej informacji o dopasowaniu wzorców
, zwłaszcza ostatnia część o operatorach ~>=~
i ~<~
.