模糊查詢(pg_bigm)
pg_bigm是阿里云產(chǎn)品RDS Postgresql的一款插件,該插件提供了全文本搜索能力,允許創(chuàng)建一個(gè)二元語法(2-gram)的GIN索引來加速搜索過程。
您可以加入RDS PostgreSQL插件交流釘釘群(103525002795),進(jìn)行咨詢、交流和反饋,獲取更多關(guān)于插件的信息。
前提條件
實(shí)例為RDS PostgreSQL 10或以上版本。
說明暫不支持RDS PostgreSQL 17。
實(shí)例內(nèi)核小版本為20230830或以上。
重要20230830內(nèi)核小版本之前已支持此插件,但為了規(guī)范插件管理,提升RDS PostgreSQL在插件側(cè)的安全防護(hù),RDS計(jì)劃在內(nèi)核版本迭代中陸續(xù)對部分存在安全風(fēng)險(xiǎn)的插件進(jìn)行優(yōu)化,部分插件在低內(nèi)核小版本無法創(chuàng)建,更多信息,請參見【產(chǎn)品/功能變更】RDS PostgreSQL限制創(chuàng)建插件說明。
如果您的實(shí)例內(nèi)核小版本低于20230830,且已經(jīng)使用了此插件,則不影響使用。
如果您首次創(chuàng)建或重新創(chuàng)建此插件,請升級內(nèi)核小版本到最新。
使用該插件前,需要將pg_bigm加入到shared_preload_libraries參數(shù)中。
您可以使用RDS PostgreSQL參數(shù)設(shè)置功能,為shared_preload_libraries參數(shù)添加pg_bigm。具體操作,請參見設(shè)置實(shí)例參數(shù)。
與pg_trgm異同
pg_trgm是RDS Postgresql的另一款插件,使用3-gram的模型來實(shí)現(xiàn)全文本搜索。pg_bigm插件是在pg_trgm基礎(chǔ)上繼續(xù)開發(fā)的,兩者的區(qū)別如下。
功能和特性 | pg_trgm | pg_bigm |
全文搜索的短語匹配方法 | 3-gram | 2-gram |
支持的索引類型 | GIN和GIST | GIN |
支持的全文本搜索操作符號 |
|
|
非字母語言的全文本搜索 | 不支持 | 支持 |
帶有1~2個(gè)字符的關(guān)鍵字的全文本搜索 | 慢 | 快 |
相似性搜索 | 支持 | 支持 |
最大可以索引的列大小 | 238,609,291字節(jié)(約228 MB) | 107,374,180字節(jié)(約102 MB) |
注意事項(xiàng)
建立GIN索引的列的長度不可以超過107,374,180字節(jié)(約102 MB)。
如果數(shù)據(jù)庫中存儲的內(nèi)容語言是非ASCII,則建議將數(shù)據(jù)庫的編碼方式改為UTF8。
說明查詢當(dāng)前數(shù)據(jù)庫的編碼方式命令為
select pg_encoding_to_char(encoding) from pg_database where datname = current_database();
。
基本操作
創(chuàng)建插件
postgres=> create extension pg_bigm; CREATE EXTENSION
創(chuàng)建索引
postgres=> CREATE TABLE pg_tools (tool text, description text); CREATE TABLE postgres=> INSERT INTO pg_tools VALUES ('pg_hint_plan', 'Tool that allows a user to specify an optimizer HINT to PostgreSQL'); INSERT 0 1 postgres=> INSERT INTO pg_tools VALUES ('pg_dbms_stats', 'Tool that allows a user to stabilize planner statistics in PostgreSQL'); INSERT 0 1 postgres=> INSERT INTO pg_tools VALUES ('pg_bigm', 'Tool that provides 2-gram full text search capability in PostgreSQL'); INSERT 0 1 postgres=> INSERT INTO pg_tools VALUES ('pg_trgm', 'Tool that provides 3-gram full text search capability in PostgreSQL'); INSERT 0 1 postgres=> CREATE INDEX pg_tools_idx ON pg_tools USING gin (description gin_bigm_ops); CREATE INDEX postgres=> CREATE INDEX pg_tools_multi_idx ON pg_tools USING gin (tool gin_bigm_ops, description gin_bigm_ops) WITH (FASTUPDATE = off); CREATE INDEX
執(zhí)行全文本搜索
postgres=> SELECT * FROM pg_tools WHERE description LIKE '%search%'; tool | description ---------+--------------------------------------------------------------------- pg_bigm | Tool that provides 2-gram full text search capability in PostgreSQL pg_trgm | Tool that provides 3-gram full text search capability in PostgreSQL (2 rows)
使用
=%
操作符執(zhí)行相似性搜索postgres=> SET pg_bigm.similarity_limit TO 0.2; SET postgres=> SELECT tool FROM pg_tools WHERE tool =% 'bigm'; tool --------- pg_bigm pg_trgm (2 rows)
卸載插件
postgres=> drop extension pg_bigm; DROP EXTENSION
插件常用函數(shù)
likequery函數(shù)
作用:生成可以被LIKE關(guān)鍵字識別的字符串。
參數(shù):1個(gè)請求參數(shù),類型為字符串。
返回值:可以被LIKE關(guān)鍵字識別的搜索字符串。
實(shí)現(xiàn)原理:
在關(guān)鍵詞前后添加
%
符號。使用
\
來自動轉(zhuǎn)義符號%
。
示例如下:
postgres=> SELECT likequery('pg_bigm has improved the full text search performance by 200%'); likequery ------------------------------------------------------------------- %pg\_bigm has improved the full text search performance by 200\%% (1 row) postgres=> SELECT * FROM pg_tools WHERE description LIKE likequery('search'); tool | description ---------+--------------------------------------------------------------------- pg_bigm | Tool that provides 2-gram full text search capability in PostgreSQL pg_trgm | Tool that provides 3-gram full text search capability in PostgreSQL (2 rows)
show_bigm函數(shù)
作用:返回給定字符串的所有2-gram元素的集合。
參數(shù):1個(gè)請求參數(shù),類型為字符串。
返回值:數(shù)組,包含所有的2-gram元素。
實(shí)現(xiàn)原理:
在字符串前后添加空格字符。
計(jì)算所有的2-gram子串。
示例如下:
postgres=> SELECT show_bigm('full text search'); show_bigm ------------------------------------------------------------------ {" f"," s"," t",ar,ch,ea,ex,fu,"h ","l ",ll,rc,se,"t ",te,ul,xt} (1 row)
bigm_similarity函數(shù)
作用:計(jì)算兩個(gè)字符串的相似度。
參數(shù):2個(gè)請求參數(shù),類型為字符串。
返回值:浮點(diǎn)數(shù),表示相似度。
實(shí)現(xiàn)原理:
統(tǒng)計(jì)兩個(gè)字符串共有的2-gram元素。
相似度范圍是[0, 1],0代表兩個(gè)字符串完全不一樣,1代表兩個(gè)字符串一樣。
說明由于計(jì)算2-gram時(shí),會在字符串前后添加空格,于是
ABC
和B
的相似度為0,ABC
和A
的相似度為0.25。bigm_similarity函數(shù)是大小寫敏感的,例如
ABC
和abc
的相似度為0。
示例如下:
postgres=> SELECT bigm_similarity('full text search', 'text similarity search'); bigm_similarity ----------------- 0.5714286 (1 row) postgres=> SELECT bigm_similarity('ABC', 'A'); bigm_similarity ----------------- 0.25 (1 row) postgres=> SELECT bigm_similarity('ABC', 'B'); bigm_similarity ----------------- 0 (1 row) postgres=> SELECT bigm_similarity('ABC', 'abc'); bigm_similarity ----------------- 0 (1 row)
pg_gin_pending_stats函數(shù)
作用:返回GIN索引的pending list中頁面和元組的個(gè)數(shù)。
參數(shù):1個(gè),GIN索引的名字或者OID。
返回值:2個(gè),pending list中頁面的數(shù)量和元組的數(shù)量。
說明如果GIN索引創(chuàng)建時(shí),指定參數(shù)FASTUPDATE為False,則該GIN索引不存在pending list,即返回結(jié)果為0。
示例如下:
postgres=> SELECT * FROM pg_gin_pending_stats('pg_tools_idx'); pages | tuples -------+-------- 0 | 0 (1 row)
插件行為控制
pg_bigm.last_update
該插件的最后更新日期,只讀參數(shù),無法修改。
示例如下:
SHOW pg_bigm.last_update;
pg_bigm.enable_recheck
決定是否進(jìn)行recheck。
說明建議您保持默認(rèn)值(ON)以保證結(jié)果正確性。
示例如下:
postgres=> CREATE TABLE tbl (doc text); CREATE TABLE postgres=> INSERT INTO tbl VALUES('He is awaiting trial'); INSERT 0 1 postgres=> INSERT INTO tbl VALUES('It was a trivial mistake'); INSERT 0 1 postgres=> CREATE INDEX tbl_idx ON tbl USING gin (doc gin_bigm_ops); CREATE INDEX postgres=> SET enable_seqscan TO off; SET postgres=> EXPLAIN ANALYZE SELECT * FROM tbl WHERE doc LIKE likequery('trial'); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on tbl (cost=20.00..24.01 rows=1 width=32) (actual time=0.020..0.021 rows=1 loops=1) Recheck Cond: (doc ~~ '%trial%'::text) Rows Removed by Index Recheck: 1 Heap Blocks: exact=1 -> Bitmap Index Scan on tbl_idx (cost=0.00..20.00 rows=1 width=0) (actual time=0.013..0.013 rows=2 loops=1) Index Cond: (doc ~~ '%trial%'::text) Planning Time: 0.117 ms Execution Time: 0.043 ms (8 rows) postgres=> postgres=> SELECT * FROM tbl WHERE doc LIKE likequery('trial'); doc ---------------------- He is awaiting trial (1 row) postgres=> SET pg_bigm.enable_recheck = off; SET postgres=> SELECT * FROM tbl WHERE doc LIKE likequery('trial'); doc -------------------------- He is awaiting trial It was a trivial mistake (2 rows)
pg_bigm.gin_key_limit
限制用于全文本搜索的2-gram元素的最大個(gè)數(shù),默認(rèn)為0,0代表使用所有的2-gram元素。
說明如果發(fā)現(xiàn)使用所有的2-gram元素導(dǎo)致性能下降,可以調(diào)整該參數(shù)值,限制2-gram元素的個(gè)數(shù)來提高性能。
pg_bigm.similarity_limit
設(shè)置相似度閾值,相似度超過這個(gè)閾值的元組會做為相似性搜索的結(jié)果。