RUM:基于 GIN 索引的改进型倒排索引
RUM 是一个扩展,它为 Postgres 添加了 RUM 索引。
RUM 索引基于 GIN,它在发布树中存储额外的条目级信息。例如,词素的位置信息或时间戳。与 GIN 相比,它可以利用这些信息来进行更快的仅索引扫描,用于
- 短语搜索
- 使用文本距离运算符进行排序的文本搜索
- 使用按一些未索引的附加列(例如,时间戳)排序的文本
SELECT。
当可能的键高度可重复时,RUM 效果最佳。也就是说,所有文本都由有限数量的单词组成,因此每个词素的索引可以显著提高搜索包含单词组合或短语的文本的速度。
主要的排序运算符是
tsvector <=> tsquery | float4 | tsvector 和 tsquery 之间的距离。value <=> value | float8 | 两个值之间的距离。
其中 value 是 timestamp、timestamptz、int2、int4、int8、float4、float8、money 和 oid
用法#
启用扩展#
您可以通过在 Supabase 控制台中启用扩展来开始使用 rum。
- 转到仪表板中的 数据库 页面。
- 在侧边栏中单击 扩展。
- 搜索 "rum" 并启用该扩展。
语法#
对于类型:tsvector#
为了理解以下内容,您可能需要先查看 官方 Postgres 文本搜索文档
rum_tsvector_ops
1CREATE TABLE test_rum(t text, a tsvector);23CREATE TRIGGER tsvectorupdate4BEFORE UPDATE OR INSERT ON test_rum5FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('a', 'pg_catalog.english', 't');67INSERT INTO test_rum(t) VALUES ('The situation is most beautiful');8INSERT INTO test_rum(t) VALUES ('It is a beautiful');9INSERT INTO test_rum(t) VALUES ('It looks like a beautiful place');1011CREATE INDEX rumidx ON test_rum USING rum (a rum_tsvector_ops);现在我们可以执行使用文本距离运算符排序的 tsvector 选择
1SELECT t, a `<=>` to_tsquery('english', 'beautiful | place') AS rank2 FROM test_rum3 WHERE a @@ to_tsquery('english', 'beautiful | place')4 ORDER BY a `<=>` to_tsquery('english', 'beautiful | place');5 t | rank6---------------------------------+---------7 It looks like a beautiful place | 8.224678 The situation is most beautiful | 16.44939 It is a beautiful | 16.449310(3 rows)rum_tsvector_addon_ops
1CREATE TABLE tsts (id int, t tsvector, d timestamp);2CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d)3 WITH (attach = 'd', to = 't');现在我们可以执行使用附加列上的距离运算符排序的选择
1SELECT id, d, d `<=>` '2016-05-16 14:21:25' FROM tsts WHERE t @@ 'wr&qh' ORDER BY d `<=>` '2016-05-16 14:21:25' LIMIT 5;2 id | d | ?column?3-----+---------------------------------+---------------4 355 | Mon May 16 14:21:22.326724 2016 | 2.6732765 354 | Mon May 16 13:21:22.326724 2016 | 3602.6732766 371 | Tue May 17 06:21:22.326724 2016 | 57597.3267247 406 | Wed May 18 17:21:22.326724 2016 | 183597.3267248 415 | Thu May 19 02:21:22.326724 2016 | 215997.3267249(5 rows)对于类型:anyarray#
rum_anyarray_ops
这个运算符类存储长度为数组的 anyarray 元素。它支持运算符 &&、@>、<@、=、% 运算符。它还支持使用 <=> 运算符进行排序。
1CREATE TABLE test_array (i int2[]);2INSERT INTO test_array VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}');3CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);现在我们可以使用索引扫描执行查询
1SELECT * FROM test_array WHERE i && '{1}' ORDER BY i `<=>` '{1}' ASC;2 i3-----------4 {1}5 {1,2}6 {1,2,3}7 {1,2,3,4}8(4 rows)rum_anyarray_addon_ops
它与 rum_tsvector_addon_ops 相同,即允许使用附加列上的距离运算符对选择结果进行排序。
限制#
RUM 由于以下原因,构建和插入时间比 GIN 慢
- 它更大,因为索引中存储了额外的属性。
- 它使用通用的 WAL 记录。