Postgres:为什么添加索引会减慢正则表达式查询的速度?

用户124114

keyvalues在 Postgres 中有一个 TEXT列:

select * from test5 limit 5;

 id |                      keyvalues
----+------------------------------------------------------
  1 | ^ first 1 | second 3
  2 | ^ first 1 | second 2 ^ first 2 | second 3
  3 | ^ first 1 | second 2 | second 3
  4 | ^ first 2 | second 3 ^ first 1 | second 2 | second 2
  5 | ^ first 2 | second 3 ^ first 1 | second 3

我的查询必须^从匹配的中间排除字符,所以我使用正则表达式:

explain analyze select count(*) from test5 where keyvalues ~* '\^ first 1[^\^]+second 0';

                                                              QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------
 Finalize Aggregate  (cost=78383.31..78383.32 rows=1 width=8) (actual time=7332.030..7332.030 rows=1 loops=1)
   ->  Gather  (cost=78383.10..78383.30 rows=2 width=8) (actual time=7332.021..7337.138 rows=3 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial Aggregate  (cost=77383.10..77383.10 rows=1 width=8) (actual time=7328.155..7328.156 rows=1 loops=3)
               ->  Parallel Seq Scan on test5  (cost=0.00..77382.50 rows=238 width=0) (actual time=7328.146..7328.146 rows=0 loops=3)
                     Filter: (keyvalues ~* '\^ first 1[^\^]+second 0'::text)
                     Rows Removed by Filter: 1666668
 Planning Time: 0.068 ms
 Execution Time: 7337.184 ms

查询有效(零行匹配),但在 > 7 秒时速度太慢。

我认为用三元组索引会有所帮助,但没有运气:

create extension if not exists pg_trgm;
create index on test5 using gin (keyvalues gin_trgm_ops);

explain analyze select count(*) from test5 where keyvalues ~* '\^ first 1[^\^]+second 0';
                                                                   QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=1484.02..1484.03 rows=1 width=8) (actual time=23734.646..23734.646 rows=1 loops=1)
   ->  Bitmap Heap Scan on test5  (cost=1480.00..1484.01 rows=1 width=0) (actual time=23734.641..23734.641 rows=0 loops=1)
         Recheck Cond: (keyvalues ~* '\^ first 1[^\^]+second 0'::text)
         Rows Removed by Index Recheck: 5000005
         Heap Blocks: exact=47620
         ->  Bitmap Index Scan on test5_keyvalues_idx  (cost=0.00..1480.00 rows=1 width=0) (actual time=1756.158..1756.158 rows=5000005 loops=1)
               Index Cond: (keyvalues ~* '\^ first 1[^\^]+second 0'::text)
 Planning Time: 0.412 ms
 Execution Time: 23734.722 ms

使用 trigram 索引的查询慢了 3 倍它仍然返回正确的结果(零行)。我希望三元组索引立即找出second 0任何地方都没有字符串,并且速度非常快。

(动机:我想避免将 规范化keyvalues另一个表中,所以我希望TEXT使用文本索引和正则表达式在单个字段中对匹配逻辑进行编码。该逻辑有效,但速度太慢,JSONB 也是如此。)

格洛芬德尔

按照OP,正确的答案被赋予这里的DBA.SE用户@jjanes:

我希望三元组索引立即找出second 0任何地方都没有字符串

'second' 和 '0' 是单独的词,因此它无法检测到它们的联合缺失。似乎它可以检测到“0”的缺失,但是来自“contrib/pg_trgm/trgm_regexp.c”的这条评论似乎是相关的:

     * Note: Using again the example "foo bar", we will not consider the
     * trigram "  b", though this trigram would be found by the trigram
     * extraction code.  Since we will find " ba", it doesn't seem worth
     * trying to hack the algorithm to generate the additional trigram.

由于 0 是模式字符串中的最后一个字符,因此也不会有“0a”形式的三元组,因此它只是错过了这个机会。

即使不是因为这个限制,你的方法似乎也非常脆弱。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么 LWP::Simple::get 会减慢后续的正则表达式?

来自分类Dev

为什么在Mongodb查询中使用正则表达式会导致它扫描所有文档而不是索引?

来自分类Dev

为什么我的正则表达式会捕获周围的字符?

来自分类Dev

为什么我的正则表达式会导致无限循环?

来自分类Dev

为什么正则表达式/ [\ w \ W] + x / i运行起来会非常慢?

来自分类Dev

为什么此正则表达式会引发异常?

来自分类Dev

为什么我的正则表达式会这样做?

来自分类Dev

PHP-为什么会警告我正则表达式太大?

来自分类Dev

为什么正则表达式会匹配空值

来自分类Dev

为什么我的正则表达式会捕获周围的字符?

来自分类Dev

为什么我的正则表达式会导致无限循环?

来自分类Dev

为什么我的正则表达式会这样做?

来自分类Dev

为什么正则表达式会削减我的话?

来自分类Dev

为什么邪恶的正则表达式会导致 ReDoS?

来自分类Dev

为什么对正则表达式匹配索引未定义

来自分类Dev

正则表达式Java,为什么此正则表达式这么慢?

来自分类Dev

Postgres正则表达式:添加逗号

来自分类Dev

为什么此正则表达式查询不返回任何结果?

来自分类Dev

为什么 R 中的正则表达式搜索查询用字符串表示?

来自分类Dev

为什么IgnorePatternWhitespace破坏正则表达式?

来自分类Dev

为什么正则表达式总是返回1?

来自分类Dev

为什么此正则表达式匹配真假?

来自分类Dev

为什么IN不评估我的正则表达式?

来自分类Dev

为什么此正则表达式与结尾>

来自分类Dev

正则表达式匹配行中断,为什么?

来自分类Dev

为什么此正则表达式不匹配?

来自分类Dev

为什么我的正则表达式与此不符?

来自分类Dev

为什么此正则表达式不匹配?

来自分类Dev

正则表达式为什么不捕获“ www”。

Related 相关文章

  1. 1

    为什么 LWP::Simple::get 会减慢后续的正则表达式?

  2. 2

    为什么在Mongodb查询中使用正则表达式会导致它扫描所有文档而不是索引?

  3. 3

    为什么我的正则表达式会捕获周围的字符?

  4. 4

    为什么我的正则表达式会导致无限循环?

  5. 5

    为什么正则表达式/ [\ w \ W] + x / i运行起来会非常慢?

  6. 6

    为什么此正则表达式会引发异常?

  7. 7

    为什么我的正则表达式会这样做?

  8. 8

    PHP-为什么会警告我正则表达式太大?

  9. 9

    为什么正则表达式会匹配空值

  10. 10

    为什么我的正则表达式会捕获周围的字符?

  11. 11

    为什么我的正则表达式会导致无限循环?

  12. 12

    为什么我的正则表达式会这样做?

  13. 13

    为什么正则表达式会削减我的话?

  14. 14

    为什么邪恶的正则表达式会导致 ReDoS?

  15. 15

    为什么对正则表达式匹配索引未定义

  16. 16

    正则表达式Java,为什么此正则表达式这么慢?

  17. 17

    Postgres正则表达式:添加逗号

  18. 18

    为什么此正则表达式查询不返回任何结果?

  19. 19

    为什么 R 中的正则表达式搜索查询用字符串表示?

  20. 20

    为什么IgnorePatternWhitespace破坏正则表达式?

  21. 21

    为什么正则表达式总是返回1?

  22. 22

    为什么此正则表达式匹配真假?

  23. 23

    为什么IN不评估我的正则表达式?

  24. 24

    为什么此正则表达式与结尾>

  25. 25

    正则表达式匹配行中断,为什么?

  26. 26

    为什么此正则表达式不匹配?

  27. 27

    为什么我的正则表达式与此不符?

  28. 28

    为什么此正则表达式不匹配?

  29. 29

    正则表达式为什么不捕获“ www”。

热门标签

归档