Есть ли причина включать столбец `tsvector` в таблицу postgres, а не в индекс? - PullRequest
1 голос
/ 15 января 2020

У меня есть таблица с примерно 100 миллионами строк и текстовое поле, по которому я бы хотел выполнить поиск. Для этого у меня есть два метода, и я хотел бы знать, как влияет каждый метод на производительность.

Метод 1: Этот метод рекомендуется в каждом сообщении моего блога. видел в Интернете (например, 1 и 2 .). Идея состоит в том, чтобы дополнить таблицу столбцом ts_vector и индексировать новый столбец.
Простой пример:

CREATE TABLE articles (
    id_articles BIGSERIAL PRIMARY KEY,
    text TEXT,
    text_tsv TSVECTOR
);
CREATE INDEX articles_index ON articles USING gin(text_tsv);

, а затем используется триггер, чтобы убедиться, что text и Столбцы text_tsv остаются актуальными.
Однако мне это кажется расточительным, поскольку теперь информация TSVECTOR должна храниться как в таблице, так и в индексе, а база данных значительно усложняется. Итак, я придумал второй метод.

Метод 2: Моя идея состоит в том, чтобы исключить дополнительный столбец и изменить индекс, чтобы напрямую включить функцию to_tsvector, например, так:

CREATE TABLE articles (
    id_articles BIGSERIAL PRIMARY KEY,
    text TEXT
);
CREATE INDEX articles_index ON articles USING gin(to_tsvector(text));

Вопрос: Есть ли недостатки использования метода 2 по сравнению с методом 1?

Для моей конкретной базы данных я использовал второй метод и у меня появляется чтобы получить разумное ускорение для простых запросов одного слова (поиск занимает ~ 1 секунду). Но когда у меня есть сложные запросы с несколькими операторами & и | в функции to_tsquery (и только ~ 10 соответствующих результатов в таблице), поиск выполняется вечно (много часов). Если я переключусь на метод 1, могу ли я по какой-то причине увидеть гораздо более быстрое время запроса?

Если медленная производительность моих запросов не связана с моим выбором метода 2, есть ли что-то еще, что я мог бы быть возможность ускорить сложные запросы, построенные с to_tsquery?

Я использую postgresql 10.10.

1 Ответ

2 голосов
/ 16 января 2020

Недостатком не сохранения tsvector является то, что он должен будет повторно вычислить tsvector из необработанного текста, чтобы «перепроверить», что строка соответствует запросу. Это может быть очень медленно.

Повторные проверки необходимы, если размер битовой карты кандидата совпадает с переполнением work_mem. Для некоторых операторов всегда требуются повторные проверки, такие как операторы соответствия фраз <->, <2>, et c.

...