Добрый день, раньше с 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к строк (ну то есть можно смело списать секунду на передачу).
Вопрос - что я делаю не так с индексами? Ведь они должны подключаться с такими параметрами запроса