Я тестирую функции текстового поиска 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.