与pg_trgm匹配的正则表达式模式(三元组匹配)

时间:2017-05-28 16:30:21

标签: postgresql pattern-matching pg-trgm

我在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。

0 个答案:

没有答案