是否有任何理由在 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);
然后使用触发器确保 text
和 text_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>
等
我有一个 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);
然后使用触发器确保 text
和 text_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>
等