我在 postgresql 中有一个名为 mydata 的数据库,其中包含一个名为 text 的字段。我有兴趣进行正则表达式模式匹配,只返回匹配的片段,而不是整个文本。我知道您可以使用 pg_trgm(创建三元组匹配索引)来加快搜索速度,但是有没有办法将搜索和匹配作为一个组合语句进行?
我将提供一些上下文:
CREATE EXTENSION pg_trgm;
CREATE INDEX text_trgm_idx ON mydata USING GIN(text gin_trgm_ops);
我将使用 '(1998.{0,10})' 的示例正则表达式模式,但我实际上对任何类型的模式都感兴趣,而不仅仅是这个示例字符串。
所需的模式匹配,但似乎没有使用 pg_trgm 索引(注意标题是另一个字段,但不是我匹配的那个):
EXPLAIN ANALYZE SELECT title, regexp_matches(text, '(1998.{0,10})') FROM mydata;
Seq Scan on mydata (cost=0.00..2257.89 rows=201720 width=73)
Planning time: 0.047 ms
Execution time: 2493.105 ms
现在,添加 WHERE 字段。
EXPLAIN ANALYZE SELECT title, regexp_matches(text, '(1998.{0,10})') FROM mydata WHERE text ~ '(1998.{0,10})';
Bitmap Heap Scan on mydata (cost=28.01..35.88 rows=20 width=73)
Rows Removed by Index Recheck: 20
Heap Blocks: exact=723
-> Bitmap Index Scan on text_trgm_idx (cost=0.00..28.01 rows=2 width=0) (actual time=0.930..0.930 rows=2059 loops=1)
Index Cond: (text ~ '(1998.{0,10})'::text)
Planning time: 15.889 ms
Execution time: 1583.970 ms
但是,如果我们删除模式匹配,我们会得到更好的性能,所以我怀疑我们做了两次相同的工作:
EXPLAIN ANALYZE SELECT title FROM mydata WHERE text ~ '(1998.{0,10})';
Bitmap Heap Scan on mydata (cost=28.01..35.78 rows=2 width=41)
Recheck Cond: (text ~ '(1998.{0,10})'::text)
Rows Removed by Index Recheck: 20
Heap Blocks: exact=723
-> Bitmap Index Scan on text_trgm_idx (cost=0.00..28.01 rows=2 width=0) (actual time=1.136..1.136 rows=2059 loops=1)
Index Cond: (text ~ '(1998.{0,10})'::text)
Planning time: 1.980 ms
Execution time: 554.589 ms
此外,如果有任何关于如何在 postgres 中进行正则表达式模式匹配时获得最佳性能的建议,我将不胜感激进一步的材料。我不受限于任何版本的 postgres。