Почему индексы GiST в PostgreSQL с текстовым поиском намного медленнее, чем индексы GIN? - PullRequest
16 голосов
/ 09 октября 2009

Я тестирую функции текстового поиска PostgreSQL, используя дамп данных за сентябрь из StackOverflow в качестве примера данных. : -)

Наивный подход использования предикатов LIKE или регулярных выражений POSIX, соответствующих поиску 1,2 миллиона строк, занимает около 90-105 секунд (на моем Macbook) для полного сканирования таблицы с поиском по ключевому слову .

SELECT * FROM Posts WHERE body LIKE '%postgresql%';
SELECT * FROM Posts WHERE body ~ 'postgresql';

Неиндексированный, специальный текстовый поиск занимает около 8 минут :

SELECT * FROM Posts WHERE to_tsvector(body) @@ to_tsquery('postgresql'); 

Создание индекса GIN занимает около 40 минут :

ALTER TABLE Posts ADD COLUMN PostText TSVECTOR;
UPDATE Posts SET PostText = to_tsvector(body);
CREATE INDEX PostText_GIN ON Posts USING GIN(PostText);

(Я понимаю, что я мог бы сделать это за один шаг, определив его как индекс выражения.)

После этого запрос с помощью индекса GIN выполняется намного быстрее - это занимает около 40 миллисекунд :

SELECT * FROM Posts WHERE PostText @@ 'postgresql'; 

Однако, когда я создаю индекс GiST, результаты совершенно разные. Создание индекса занимает менее 2 минут :

CREATE INDEX PostText_GIN ON Posts USING GIST(PostText);

После этого запрос с использованием оператора текстового поиска @@ занимает 90-100 секунд . Таким образом, индексы GiST улучшают неиндексированный запрос TS с 8 минут до 1,5 минут. Но это не улучшение по сравнению с полным сканированием таблицы с LIKE. Это бесполезно в среде веб-программирования.

Я что-то упускаю для использования индексов GiST? Нужно ли предварительно кэшировать индексы в памяти или что-то еще? Я использую простую установку PostgreSQL из MacPorts без настройки.

Каков рекомендуемый способ использования индексов GiST? Или все, кто делает TS с PostgreSQL, пропускают индексы GiST и используют только индексы GIN?

PS: я знаю об альтернативах, таких как Sphinx Search и Lucene. Я просто пытаюсь узнать о возможностях, предоставляемых самим PostgreSQL.

Ответы [ 3 ]

6 голосов
/ 04 января 2011

Документы имеют хороший обзор различий в производительности между индексами GiST и GIN, если вам интересно: Типы индексов GiST и GIN .

6 голосов
/ 09 октября 2009

1001 * попробовать *

CREATE INDEX PostText_GIST ON Posts USING GIST(PostText varchar_pattern_ops);

, который создает индекс, подходящий для префиксных запросов. См. Документы PostgreSQL по Классы операторов и семейства операторов . Оператор @@ имеет смысл только для векторов членов; индекс GiST (с varchar_pattern_ops) даст отличные результаты с LIKE.

2 голосов
/ 18 июля 2013

между прочим: если это еще не было удовлетворено, то часть, где вы сделали

SELECT * FROM Posts WHERE PostText @@ 'postgresql';

должно было быть

SELECT * FROM Posts WHERE PostText @@ to_tsquery('postgresql');

...