在 PostgreSQL 的 news 頁上看到「PGroonga 3.0.0 – Multilingual fast full text search」,想到一直沒有測過 PGroonga,就找台機器測了一下。
PGroonga 是以 Groonga 為引擎提供 PostgreSQL 全文搜尋能力的套件,是個能支援 CJK 語系的全文搜尋套件。
可以先看一下支援的 column type 與對應的語法:「Reference manual | PGroonga」,可以發現基本的 text
、text[]
與 varchar
、varchar[]
都有支援,比較特別的是有 jsonb
,看起來是對裡面的 text 欄位搜尋。
另外一個比較特別的是他會去找 LIKE '%something%'
這個語法,對於無法修改的既有程式也會有幫助。
缺點方面,官方有提到產生出來的 index 會比其他的套件大,但畢竟我們在的環境要支援 CJK,場上的選手已經不多了。
另外一個缺點是目前 AWS 的 RDS 與 GCP 的 Cloud SQL 看起來都沒支援,要用的話得自己架 & 自己管,也許可以考慮用老方法,replication 接出來?
接下來就是安裝測試了,我在 x86-64 上的 Ubuntu 22.04 上面測試,就照著「Install on Ubuntu | PGroonga」這頁裡面的「How to install for system PostgreSQL」這段就可以了,裝系統的 PostgreSQL 14 以及 postgresql-14-pgroonga
,之後要用 PostgreSQL 官方的新版的話可以參考「How to install for the official PostgreSQL」這段的安裝。
後續再到「Tutorial | PGroonga」頁,針對要搜尋的欄位下 index (這邊裱格式 memos
,欄位是 content
):
CREATE INDEX ON memos USING pgroonga (content);
官方的教學文件裡是用 SET enable_seqscan = off;
關閉 sequence scan,可以用 EXPLAIN
看到使用了 index:
test=# SELECT * FROM memos WHERE content &@ ‘engine’;
id | content
—-+————————————————————————
2 | Groonga is a fast full text search engine that supports all languages.
(1 row)
test=# EXPLAIN SELECT * FROM memos WHERE content &@ ‘engine’;
QUERY PLAN
———————————————————————————
Index Scan using memos_content_idx on memos (cost=0.00..43.18 rows=1 width=36)
Index Cond: (content &@ ‘engine’::text)
(2 rows)
先拔掉 index:
test=# DROP INDEX pgroonga_content_index;
DROP INDEX
接著要塞資料,這邊拿 CQD 生的「中文假文產生器」來用,有 API 可以接比較方便。
test=# SELECT COUNT(*) FROM memos;
count
——–
100000
(1 row)
Time: 15.495 ms
接著多跑幾次測試直接用 LIKE '%台北%'
去找,可以看到大概都在 150ms 以上:
test=# SELECT COUNT(*) FROM memos WHERE content LIKE ‘%台北%’;
count
——-
710
(1 row)
Time: 178.784 ms
接著來建立 index:
test=# CREATE INDEX ON memos USING pgroonga (content);
CREATE INDEX
Time: 17638.124 ms (00:17.638)
再跑幾次同樣的 query,可以看到巨大的改善:
test=# SELECT COUNT(*) FROM memos WHERE content LIKE ‘%台北%’;
count
——-
710
(1 row)
Time: 9.876 ms