FTS(full text search) - что я делаю не так?

kamakama
Дата: 27.02.2015 17:28:06
Добрый день, раньше с FTS не приходилось контачить, а вот пришлось.
Имеем. Таблица
CREATE TABLE spr_article
(
  id bigint NOT NULL,
  clear_text text,
  tsv tsvector,
  CONSTRAINT pk_spr_article_ PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

CREATE INDEX ftidx_spr_article_0_clear_text_rus ON spr_article USING gin(to_tsvector('russian',clear_text));
CREATE INDEX ftidx_spr_article_0_clear_text_rus_gist ON spr_article USING gist(to_tsvector('russian',clear_text));

В ней 100к записей, тексты приличные, объем всей таблицы ~330 МБ. Настройки FTS стандартные. Машина - PG 9.2, Gentoo, 24 GB, 8 камней на виртуальном сервере, shared_buffers = 16GB.

Запрос
SELECT id FROM part.spr_article_0 WHERE clear_text @@ to_tsquery('путин|президент')


Создал сначала GIST - выполнялся 45 секунд, потом 42 (после того, как все должен был закэшировать)
Потом GIN - выполнялся 48 секунд, потом 45 (после того, как все должен был закэшировать)
Потом вообще сделал
SELECT id FROM part.spr_article_0 WHERE clear_text ilike '%путин%'

Чудо - всего 10 секунд. Планировщик пишет, что начхал на индексы и сканирует seq_scan несмотря ни на какие индексы.

Искал альтернативные варианты, в том числе такие:
ALTER TABLE spr_article ADD COLUMN tsv tsvector;
UPDATE spr_article SET tsv = to_tsvector('russian', clear_text);
CREATE TRIGGER tg_tsvector_update_spr_article_0 BEFORE INSERT OR UPDATE ON spr_article FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(tsv, 'russian', title, body);

SELECT id FROM part.spr_article_0 WHERE tsv @@ to_tsquery('президент & путин')

Результат - 2 секунды и 17к строк (ну то есть можно смело списать секунду на передачу).

Вопрос - что я делаю не так с индексами? Ведь они должны подключаться с такими параметрами запроса
kamakama
Дата: 27.02.2015 17:29:14
CREATE DATABASE test
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'ru_RU.UTF-8'
       LC_CTYPE = 'ru_RU.UTF-8'
       CONNECTION LIMIT = -1;
/\/\/\/\/\/\
Дата: 27.02.2015 17:35:02
kamakama,

Посмотрите на селективность индекса.
17k из 100k - последовательный просмотр будет наилучшим.
Индексы - не всегда хорошо.
kamakama
Дата: 27.02.2015 17:42:53
/\/\/\/\/\/\,

Ошибку нашел. Неверно составлен был запрос на выборку
SELECT id FROM part.spr_article_0 WHERE to_tsvector('russian',clear_text) @@ to_tsquery('russian','путин|президент')
. И индекс подключился и результаты доступа 202 мс. Тему можно закрывать