Index-y w PostgreSQL

0

Witam, chciałem użyć indeksów w postgresie aby przyspieszyć wyszukiwanaie stringów w tabeli. Nie muszę dodwać, że owa tabela ma bardzo dużą ilość rekordów, zapytanie sprawdzające pole "nazwa" (name) trwa parę ładnych minut.

Zabierając się do roboty stworzyłem indeks:

CREATE INDEX "pis_name_index" ON "public"."pis"
  ("name");

Po czym proste zapytanie z "like 'do34'" działa błyskawicznie. Explain rzeczywiście pokazuje że podczas wyszukiwania został użyty indeks:

EXPLAIN  SELECT 
*
FROM 
  public.pis
WHERE
	name like 'do34';


Bitmap Heap Scan on pis (cost=5.45..364.07 rows=91 width=3051)
  Filter: (name ~~ 'do34'::text)
  ->  Bitmap Index Scan on pis_name_index  (cost=0.00..5.43 rows=91 width=0)
        Index Cond: (name = 'do34'::text)

Modyfikuje zapytanie tak aby znalazł wszystkie rekordy których nazwa zaczyna sie od frazy do34. Pstgres po tej modyfikacji przestaje uzywać indexów do wyszukiwania:

EXPLAIN  SELECT 
*
FROM 
  public.pis
WHERE
	name like 'do34%';
  ;

Seq Scan on pis(cost=0.00..202630.96 rows=144 width=3051)
  Filter: (name ~~ 'do34%'::text)

Zapytanie spełnia wymogi wymienione na
http://wiki.postgresql.org/wiki/FAQ#Why_are_my_queries_slow.3F_Why_don.27t_they_use_my_indexes.3F więc w czym jest problem?

0

Logiczne. Nigdy do Like nie jest używany indeks.

0
Marcin.Miga napisał(a)

Logiczne. Nigdy do Like nie jest używany indeks.

Nieprawda. Przeczytaj dokumentację podaną wyżej.

Może po prostu w tabeli jest za mało danych i dlatego w tym przypadku indeks nie jest używany.

0

W dokumentacji jest informacja, że decyzja o użyciu indeksu jest podejmowana na podstawie statystyk... poza tym zawsze możesz użyć:
SET enable_seqscan TO 'off'

0

Dla zainteresowanych, nie pomogło:

ANALIZE  public.pis;

jak również

SET enable_seqscan TO 'off'

Zacząłem szukać opisu komendy CREATE INDEX, okazało się że komenda przy takim wywołaniu jak w pierwszym poście liczy skrót stringa i wrzuca go do b-drzewa co pozwala na znajdowanie stringów które są identyczne. Postgres może użyć innego algorytmu do indexowania, który pozwoli na wyszukiwanie początkowych fragmentów stringa, wystarczy dodac przy nazwie kolumny text_pattern_ops.

CREATE INDEX 
	pis
ON 
	"public"."pis" ("name" text_pattern_ops);

</quote>

1 użytkowników online, w tym zalogowanych: 0, gości: 1