12.2. Таблицы и индексы #

В предыдущем разделе приводились примеры, которые показывали, как можно выполнить сопоставление с простыми текстовыми константами. В этом разделе показывается, как находить текст в таблице, возможно с применением индексов.

12.2.2. Создание индексов #

Для ускорения текстового поиска мы можем создать индекс GIN (см. Раздел 12.9):

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body));

Заметьте, что здесь используется функция to_tsvector с двумя аргументами. В выражениях, определяющих индексы, можно использовать только функции, в которых явно задаётся имя конфигурации текстового поиска (см. Раздел 11.7). Это объясняется тем, что содержимое индекса не должно зависеть от значения параметра default_text_search_config. В противном случае содержимое индекса может быть неактуальным, если разные его элементы tsvector будут создаваться с разными конфигурациями текстового поиска и нельзя будет понять, какую именно использовать. Выгрузить и восстановить такой индекс будет невозможно.

Так как при создании индекса использовалась версия to_tsvector с двумя аргументами, этот индекс будет использоваться только в запросах, где to_tsvector вызывается с двумя аргументами и во втором передаётся имя той же конфигурации. То есть, WHERE to_tsvector('english', body) @@ 'a & b' сможет использовать этот индекс, а WHERE to_tsvector(body) @@ 'a & b' — нет. Это гарантирует, что индекс будет использоваться только с той конфигурацией, с которой создавались его элементы.

Индекс можно создать более сложным образом, определив для него имя конфигурации в другом столбце таблицы, например:

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body));

где config_name — имя столбца в таблице pgweb. Так можно сохранить имя конфигурации, связанной с элементом индекса, и, таким образом, иметь в одном индексе элементы с разными конфигурациями. Это может быть полезно, например, когда в коллекции документов хранятся документы на разных языках. И в этом случае в запросах должен использоваться тот же индекс (с таким же образом задаваемой конфигурацией), например, так: WHERE to_tsvector(config_name, body) @@ 'a & b'.

Индексы могут создаваться даже по объединению столбцов:

CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));

Ещё один вариант — создать отдельный столбец tsvector, в котором сохранить результат to_tsvector. Чтобы этот столбец автоматически синхронизировался с исходными данными, он создаётся как сохранённый генерируемый столбец. Следующий пример показывает, как можно подготовить для индексации объединённое содержимое столбцов title и body, применив функцию coalesce для получения желаемого результата, даже когда один из столбцов NULL:

ALTER TABLE pgweb
    ADD COLUMN textsearchable_index_col tsvector
               GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;

Затем мы создаём индекс GIN для ускорения поиска:

CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);

Теперь мы можем быстро выполнять полнотекстовый поиск:

SELECT title
FROM pgweb
WHERE textsearchable_index_col @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC
LIMIT 10;

Хранение вычисленного выражения индекса в отдельном столбце даёт ряд преимуществ. Во-первых, для использования индекса в запросах не нужно явно указывать имя конфигурации текстового поиска. Как показано в вышеприведённом примере, в этом случае запрос может зависеть от default_text_search_config. Во-вторых, поиск выполняется быстрее, так как для проверки соответствия данных индексу не нужно повторно выполнять to_tsvector. (Это актуально больше для индексов GiST, чем для GIN; см. Раздел 12.9.) С другой стороны, схему с индексом по выражению проще реализовать и она позволяет сэкономить место на диске, так как представление tsvector не хранится явно.

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy