Postgres 9.2 lub nowszy jest na ogół wystarczająco inteligentny, aby zdać sobie sprawę, że stan
WHERE name LIKE '%%'
nie jest selektywny i ucieka się do skanowania sekwencyjnego, ignorując indeks GiST - nawet w przypadku przygotowanych oświadczeń. robisz jednak zapłacić niewielką cenę za bezużyteczny stan.
W Postgresie 9.1 lub wcześniejszych zbudowałbym osobne zapytanie dla specjalnego przypadku.
Porównaj Notatki sekcja dla PREPARE
oświadczenie w instrukcji dla wersji 9.1
, 9.2
i 9.3
.
Zweryfikuj się
Przygotuj instrukcję i uruchom EXPLAIN ANALYZE
do przetestowania:
PREPARE plan1 (text) AS
SELECT * FROM file
WHERE name LIKE $1;
EXPLAIN ANALYZE EXECUTE plan1('%123%');
EXPLAIN ANALYZE EXECUTE plan1('%%');
Plany są zazwyczaj buforowane na czas trwania sesji.
Alternatywne zapytanie
Niezależnie od używanej wersji, jeśli zawsze przeprowadzasz wyszukiwanie pełnotekstowe (symbole wieloznaczne po lewej i prawej stronie), to zapytanie powinno być szybsze dla przygotowanej instrukcji:
SELECT * FROM files WHERE name LIKE ('%' || $1 || '%');
I przekaż wzór bez dodanych symboli wieloznacznych (%
), oczywiście. W ten sposób Postgres wie, że w czasie planowania może oczekiwać wzorca zawartego w symbolach wieloznacznych.
->Demo SQLfiddle.
Zwróć uwagę na sekwencyjne skanowanie pustego LIKE i różnicę wydajności między dwoma planami.
SQLfiddle różni się bardzo, w zależności od obciążenia itp. Pojedynczy przebieg może nie być niezawodny. Lepiej przetestuj w swoim środowisku i uruchom każdą instrukcję kilka razy, aby nasycić pamięć podręczną i wyeliminować szum.