是否有任何理由在 postgres table 而不是索引中包含一个 `tsvector` 列?

Is there any reason to include a `tsvector` column in a postgres table rather than in the index?

我有一个 table,其中包含大约 1 亿行和一个我想要搜索的文本字段。我想出了两种方法来执行此操作,我想知道每种方法对性能的影响。

方法一:这是我在网上看到的每个博客post都推荐的方法(例如1 and 2)。 这个想法是用 ts_vector 列扩充 table 并索引新列。
一个简单的例子是:

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

然后使用触发器确保 texttext_tsv 列保持最新。
然而,这对我来说似乎很浪费,因为现在 TSVECTOR 信息必须存储在 table 和索引中,并且数据库变得更加复杂。 所以我想出了第二种方法。

方法二: 我的想法是消除多余的列并更改索引以直接包含 to_tsvector 函数,如下所示:

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

问题:与方法 1 相比,使用方法 2 有什么缺点吗?

对于我的特定数据库,我使用了第二种方法,我似乎对单个单词的简单查询获得了合理的加速(搜索需要约 1 秒)。但是,当我在 to_tsquery 函数中使用多个 &| 运算符进行复杂查询时(并且在 table 中只有 ~10 个匹配结果),搜索将永远 运行(很多小时)。如果我切换到方法 1,我是否会因为某种原因看到更快的查询时间?

如果我的查询性能低下不是因为我选择了方法 2,还有什么我可以做的来加速使用 to_tsquery 构建的复杂查询吗?

我正在使用 postgresql 10.10。

不存储 tsvector 的缺点是必须从原始文本重新计算 tsvector 以便 "recheck" 该行满足查询。这可能会很慢。

如果候选匹配的位图大小溢出,则需要重新检查work_mem。对于某些运算符,始终需要重新检查,例如短语匹配运算符 <-><2>