rum(全文檢索加速)
rum
插件擴展了GIN索引(通用倒排索引)的基本概念,基于GIN索引Access Method代碼,實現(xiàn)了更快的全文搜索方法。
前提條件
支持的PolarDB PostgreSQL版(兼容Oracle)的版本如下:
Oracle語法兼容 2.0(內(nèi)核小版本2.0.14.3.0及以上)。
您可通過如下語句查看PolarDB PostgreSQL版(兼容Oracle)的內(nèi)核小版本號:
show polar_version;
背景
GIN索引支持通過tsvector
和tsquery
兩種數(shù)據(jù)類型進行全文檢索,但是有如下幾個問題:
排序慢:需要有關(guān)詞匯的位置信息才能進行排序。由于GIN索引不存儲詞匯的位置,因此在索引掃描之后,需要額外的掃描來檢索詞匯位置。
短語查詢慢:GIN索引需要位置信息來執(zhí)行短語搜索。
時間戳排序慢:GIN索引無法在帶有詞素的索引中存儲一些相關(guān)信息,因此需要執(zhí)行額外的掃描。
RUM
插件基于GIN索引,通過在RUM索引中存儲額外的信息(詞匯位置或時間戳的位置信息)來解決以上問題。
由于RUM索引需要存儲除密鑰之外的其他信息以及使用通用的WAL日志記錄,RUM索引構(gòu)建和插入時間慢于GIN索引。
rum通用操作符
rum
模塊提供以下操作符:
操作符 | 返回值數(shù)據(jù)類型 | 描述 |
| float4 | 用于計算 |
| float8 | 用于計算兩個時間戳之間的距離。 |
| float8 | 用于計算所有小于當(dāng)前時間戳的距離。 |
| float8 | 用于計算所有大于當(dāng)前時間戳的距離。 |
<=>
、<=|
和|=>
操作符也適用于以下數(shù)據(jù)類型:
timestamptz
int2
int4
int8
float4
float8
money
oid
使用方法
創(chuàng)建插件
您可以執(zhí)行以下SQL語句安裝插件。
CREATE EXTENSION rum;
如果在滿足版本要求的條件下創(chuàng)建插件失敗,請聯(lián)系我們處理。
函數(shù)使用介紹
rum_tsvector_ops
用于存儲帶有位置信息的tsvector
詞組,支持按<=>
運算符排序和前綴搜索。示例:
準(zhǔn)備測試數(shù)據(jù):
CREATE TABLE test_rum(t text, a tsvector); CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON test_rum FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger('a', 'pg_catalog.english', 't'); INSERT INTO test_rum(t) VALUES ('The situation is most beautiful'); INSERT INTO test_rum(t) VALUES ('It is a beautiful'); INSERT INTO test_rum(t) VALUES ('It looks like a beautiful place');
創(chuàng)建rum索引:
CREATE INDEX rumidx ON test_rum USING rum (a rum_tsvector_ops);
執(zhí)行如下查詢:
查詢語句一:
SELECT t, a <=> to_tsquery('english', 'beautiful | place') AS rank FROM test_rum WHERE a @@ to_tsquery('english', 'beautiful | place') ORDER BY a <=> to_tsquery('english', 'beautiful | place');
查詢結(jié)果如下:
t | rank ---------------------------------+---------- It looks like a beautiful place | 8.22467 The situation is most beautiful | 16.44934 It is a beautiful | 16.44934 (3 rows)
查詢語句二:
SELECT t, a <=> to_tsquery('english', 'place | situation') AS rank FROM test_rum WHERE a @@ to_tsquery('english', 'place | situation') ORDER BY a <=> to_tsquery('english', 'place | situation');
查詢結(jié)果如下:
t | rank ---------------------------------+---------- The situation is most beautiful | 16.44934 It looks like a beautiful place | 16.44934 (2 rows)
rum_tsvector_hash_ops
用于存儲tsvector
詞組的哈希值和位置信息。支持按<=>
運算符排序,但不支持前綴搜索。說明rum_tsvector_hash_ops
支持使用<=>
、<=|
、|=>
操作符進行排序,可以與rum_tsvector_addon_ops
、rum_tsvector_hash_addon_ops
和rum_anyarray_addon_ops
一起使用。rum_TYPE_ops
為操作符,適應(yīng)的數(shù)據(jù)類型和支持的操作符如下:適用數(shù)據(jù)類型:
int2
,int4
,int8
,float4
,float8
,money
,oid
,time
,timetz
,date
,interval
,macaddr
,inet
,cidr
,text
,varchar
,char
,bytea
,bit
,varbit
,numeric
,timestamp
,timestamptz
。支持的操作符:
<
、<=
、=
、>=
、>
操作符支持所有數(shù)據(jù)類型,<=>
、<=|
、|=>
操作符支持int2
、int4
、int8
、float4
、float8
、money
、oid
、timestamp
、timestamptz
數(shù)據(jù)類型。rum_tsvector_addon_ops
用于存儲tsvector
詞法,以及模塊字段支持的任何詞法。示例:
準(zhǔn)備數(shù)據(jù):
CREATE TABLE tsts (id int, t tsvector, d timestamp); \copy tsts from 'external/rum/data/tsts.data' CREATE INDEX tsts_idx ON tsts USING rum (t rum_tsvector_addon_ops, d) WITH (attach = 'd', to = 't');
執(zhí)行如下計劃:
EXPLAIN (costs off) SELECT 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; QUERY PLAN ----------------------------------------------------------------------------------- Limit -> Index Scan using tsts_idx on tsts Index Cond: (t @@ '''wr'' & ''qh'''::tsquery) Order By: (d <=> '2016-05-16 14:21:25'::timestamp without time zone) (4 rows)
執(zhí)行如下查詢命令:
SELECT 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;
查詢結(jié)果如下:
id | d | ?column? -----+----------------------------+--------------- 355 | 2016-05-16 14:21:22.326724 | 2.673276 354 | 2016-05-16 13:21:22.326724 | 3602.673276 371 | 2016-05-17 06:21:22.326724 | 57597.326724 406 | 2016-05-18 17:21:22.326724 | 183597.326724 415 | 2016-05-19 02:21:22.326724 | 215997.326724 (5 rows)
說明由于后綴樹具有固定長度的右邊界和固定長度的無子節(jié)點后綴項,RUM在使用按引用傳遞附加信息進行排序來創(chuàng)建索引時可能有缺陷。
rum_tsvector_hash_addon_ops
用于存儲tsvector
詞庫的哈希值以及任何支持模塊的字段,不支持前綴搜索。rum_tsquery_ops
適用tsquery
數(shù)據(jù)類型,用于在其他信息中存儲查詢樹的分支。示例:
準(zhǔn)備數(shù)據(jù):
CREATE TABLE test_array (i int2[]); INSERT INTO test_array VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}'); CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);
執(zhí)行如下指令:
SET enable_seqscan TO off; EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; QUERY PLAN ------------------------------------------ Index Scan using idx_array on test_array Index Cond: (i && '{1}'::smallint[]) Order By: (i <=> '{1}'::smallint[]) (3 rows)
執(zhí)行如下查詢:
SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC;
查詢結(jié)果如下:
i ----------- {1} {1,2} {1,2,3} {1,2,3,4} (4 rows)
rum_anyarray_ops
用于存儲具有數(shù)組長度的anyarrray
元素。支持運算符&&
、@>
、<@
、=
、%
,支持按<=>
運算符排序。示例:
準(zhǔn)備數(shù)據(jù):
CREATE TABLE test_array (i int2[]); INSERT INTO test_array VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}'); CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops);
執(zhí)行如下指令:
SET enable_seqscan TO off; EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; QUERY PLAN ------------------------------------------ Index Scan using idx_array on test_array Index Cond: (i && '{1}'::smallint[]) Order By: (i <=> '{1}'::smallint[]) (3 rows)
執(zhí)行如下查詢:
SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC;
查詢結(jié)果如下:
i ----------- {1} {1,2} {1,2,3} {1,2,3,4} (4 rows)
rum_anyarray_addon_ops
用于存儲anyarrray
元素以及模塊字段支持的任何元素。
卸載插件
您可以執(zhí)行以下SQL語句卸載插件。
DROP EXTENSION rum;
相關(guān)參考
RUM插件的更多信息可參考rum。