Сопоставление регулярных выражений с 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 ответов

Другие вопросы по тегам