Здравствуйте!
Разбираюсь с полнотекстовым поиском. Столкнулся с такой проблемой:
billing=# select count(*) from a where to_tsvector('russian', body) @@ to_tsquery('пакет');
count
--------
208488
(1 запись)
Время: 31376,000 мс
billing=# select count(*) from a where body like '%пакет%';
count
--------
208488
(1 запись)
Время: 15868,000 мс
Т.е. полнотекстовый поиск в два раза медленнее простого LIKE'а.
Таблица:
billing=# \d a
Таблица "public.a"
Колонка | Тип | Модификаторы
---------+------------------------+------------------------------------------------
id | integer | not null default nextval('a_id_seq'::regclass)
body | character varying(255) |
Индексы:
"fts_body" gist (to_tsvector('russian'::regconfig, body::text))
Всего записей:
billing=# select count(*) from a;
count
---------
1052481
(1 запись)
Время: 19540,000 мс
Смена типа индекса (GIST/GIN) на ситуацию не влияет. Вынесение ts_vector('russian', body) в отдельную колонку и создание индекса по ней - тоже.
Также непонятен принцип работы GINа:
billing=# drop index fts_body;
DROP INDEX
Время: 712,000 мс
billing=# create index fts_body on a using gin(to_tsvector('russian', body));
CREATE INDEX
Время: 97334,360 мс
billing=# explain select count(*) from a where to_tsvector('russian', body) @@ to_tsquery('пакет');
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Aggregate (cost=3890.02..3890.03 rows=1 width=0)
-> Bitmap Heap Scan on a (cost=32.62..3887.39 rows=1052 width=0)
Recheck Cond: (to_tsvector('russian'::regconfig, (body)::text) @@ to_tsquery('пакет'::text))
-> Bitmap Index Scan on fts_body (cost=0.00..32.36 rows=1052 width=0)
Index Cond: (to_tsvector('russian'::regconfig, (body)::text) @@ to_tsquery('пакет'::text))
(5 rows)
Время: 0,000 мс
Что означает Recheck Cond? В документации указано, что проверка результатов производится только в GIST для отсеивания ложных совпадений. Если я правильно понял, здесь мы наблюдаем то же самое с GIN-индексом.