1

Temat: LIKE '%foo'

Witam.

Przenoszenie bazy z MySQL na PgSQL i problem.

Mianowicie mam tabelę gdzie jedna z kolumn zawiera serial postaci A12345/A1234/1234.
Aplikacja często szuka po tej kolumnie i ma specyficzne wymagania co do wyników. Mianowicie fraza '123' ma zwrócić wszystkie rekordy w których ona występuje w dowolnym miejscu czyli np.

A1234/V1111/1434
C3333/D1231/1222
C3333/R3332/1123
itp.

Do tej pory działało to w sposób:

SELECT * FROM seriale WHERE serial LIKE '%123%';

i na MySQL działało szybko i sprawnie bez indeksowania (bo się nie da indeksować LIKE '%foo').

Natomiast na PgSQL działa to STRASZNIE wolno. Różnica jest kolosalna np. 5000 zapytań wykonanych jedno po drugim na MySQL trwało 0.5s a na PgSQL 45.0s! Jeśli natomiast chcę mieć możliwość szukania "case insensitive" jak domyślnie w MySQL to przy pomocy ILIKE w PgSQL trwa to UWAGA! 1.3 MINUTY!!

Podobno można zaindeksować takie wyszukiwanie przy pomocy Full Text Search, ale nie mam pojęcia jak skonfigurować to aby otrzymać takie wyniki jakie są mi potrzebne.
Próbowałem też użyć pg_trgm ale wyniki są dalekie od zadowalających.

Może ktoś pomoże?

2

Odp: LIKE '%foo'

Duża ta tabela? Statystyki odświeżone?

3

Odp: LIKE '%foo'

Tabela ok. 10 000 rek.

Co masz na myśli mówiąc statystyki?

4

Odp: LIKE '%foo'

Postgres do optymalizacji planu wykonania zapytań stosuje statystyki (coś a'la optymalizator kosztowy).  Statystyki przechowuje w tabelach. Statystyki odświeża się poleceniem analyze. Dobrze też robić coś jakiś czas odkurzanie (polecenie vacuum).

5

Odp: LIKE '%foo'

Poka plan zapytania wink

Fultext nie wiele ci da bo masz ciąg znaków bez białych znaków, więc będzie mu ciężko coś z tego wyliczyć.

1. Można by spróbować indexy funkcyjne ma przeszukiwania, ale to już ostateczność smile
2. Rozbić pole tak aby doprowadzić do domowości argumentów, ale pewnie nie ma takiej możliwości ;]

Pozdrawiam
Pawel Socha