> Как работает полнотекстовый индекс GIN в PostgreSQL (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: Wildberries

Стек: Go, PostgreSQL

> Пример ответа

GIN (Generalized Inverted Index) в PostgreSQL - это индекс для полнотекстового поиска, оптимизированный для работы с составными значениями, такими как tsvector. В отличие от B-tree, GIN хранит не сами значения, а их компоненты: для каждого уникального лексемы (слова) создаётся список ссылок на строки, где она встречается. Это позволяет эффективно выполнять поиск по операторам @@ (соответствие tsquery) и @> (вхождение массива).

При вставке или обновлении строки GIN разбивает tsvector на лексемы, нормализует их (убирает стоп-слова, приводит к базовой форме) и добавляет записи в индекс. Поиск по запросу to_tsquery('russian', 'быстрый & поиск') сначала находит все строки, содержащие обе лексемы, а затем выполняет пересечение списков. Для ускорения операций вставки GIN использует буферные страницы (pending list) - изменения накапливаются в памяти и сбрасываются на диск при достижении порога (gin_pending_list_limit).

В Go-приложении с драйвером pgx вы можете создать такой индекс:

SQL
CREATE INDEX idx_articles_fts ON articles USING GIN(to_tsvector('russian', title || ' ' || body));

Запрос для поиска:

GO
rows, err := conn.Query(ctx, "SELECT id, title FROM articles WHERE to_tsvector('russian', title || ' ' || body) @@ to_tsquery('russian', $1)", query)

GIN эффективен для редких слов (низкая селективность), но может быть медленнее B-tree для частых обновлений. Для ускорения используйте gin_trgm_ops (расширение pg_trgm) для нечёткого поиска или GIST для геоданных.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью