即使在使用了GIN索引之后,我也不能让类型为column_name collate "default" ilike 'abc%'的查询在我的Postgres 12表上有效地工作(以亚秒为单位运行).

问题以及如何重现问题:

My table:

CREATE TABLE test_policy(
id SERIAL not null PRIMARY KEY, 
policy_number varchar(255) not null COLLATE "english_ci");

insert 10000000 records

insert into test_policy(policy_number) 
select (select prefix || '/' || suffix from 
  (select prefix from (select string_agg(x, '') from (select     
    start_arr[ 1 + ( (random() * 100)::int) % 13] from (select 
    '{AB,CD,EF,GH,IJ,KL,MN,OP,QR,ST,UV,WX,YZ}'::text[] as start_arr)    
     sy, generate_series(1, 3 + (0*generator)) as g)as str2(x)) as 
     s(prefix)) as pre(prefix), (select suffix from (select n[1 + 
    (random() * 100)::int % 10] from (select '{00, 01, 02, 03, 04, 
     05, 06, 07, 08, 09, 10}'::text[]) as num(n)) as s(suffix)) as    
    suf(suffix)
) FROM generate_series (1,10000000) as generator 
on conflict do nothing;

Create GIN index

CREATE INDEX trgm_idx_policy_number ON test_policy USING gin (policy_number gin_trgm_ops);

分析下面的查询,您将看到没有 Select 索引,运行时间约为2.5秒.我想知道为什么以及如何进行此查询以获取索引.我有很多具有上述样式的表,查询使用COLLATE "default" ilike个.

explain analyse select count(id) from test_policy where policy_number  COLLATE "default" ilike 'EFWXMN%';

Output

Finalize Aggregate  (cost=107139.59..107139.60 rows=1 width=8) (actual time=2512.638..2517.028 rows=1 loops=1)
  ->  Gather  (cost=107139.38..107139.59 rows=2 width=8) (actual time=2512.318..2517.007 rows=3 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        ->  Partial Aggregate  (cost=106139.38..106139.39 rows=1 width=8) (actual time=2484.685..2484.686 rows=1 loops=3)
              ->  Parallel Seq Scan on test_policy  (cost=0.00..106138.33 rows=417 width=4) (actual time=11.753..2483.982 rows=1489 loops=3)
                    Filter: ((policy_number)::text ~~* 'EFWXMN%'::text)
                    Rows Removed by Filter: 3331844
Planning Time: 0.424 ms
JIT:
  Functions: 17
  Options: Inlining false, Optimization false, Expressions true, Deforming true
  Timing: Generation 5.328 ms, Inlining 0.000 ms, Optimization 3.073 ms, Emission 25.693 ms, Total 34.094 ms
Execution Time: 2520.419 ms

My approach of optimizing query

但是,如果我将表的COLUMN:POLICY_NUMBER更改为:

ALTER TABLE test_policy
ALTER COLUMN policy_number TYPE varchar  ;

并再次运行类似的查询,您将注意到正在使用TRGM_IDX_POLICY_NUMBER,运行时间约为100毫秒.

explain analyse select count(id) from test_policy where policy_number ilike 'EFWXMN%';

output

Aggregate  (cost=10371.96..10371.97 rows=1 width=8) (actual time=49.658..49.660 rows=1 loops=1)
  ->  Bitmap Heap Scan on test_policy  (cost=124.80..10363.96 rows=3200 width=4) (actual time=34.038..49.203 rows=4395 loops=1)
        Recheck Cond: ((policy_number)::text ~~* 'EFWXMN%'::text)
        Heap Blocks: exact=4209
        ->  Bitmap Index Scan on trgm_idx_policy_number  (cost=0.00..124.00 rows=3200 width=0) (actual time=33.598..33.598 rows=4395 loops=1)
              Index Cond: ((policy_number)::text ~~* 'EFWXMN%'::text)
Planning Time: 0.134 ms
Execution Time: 49.814 ms

您能解释一下为什么这次使用杜松子wine 索引,运行时间是亚秒级的吗?

推荐答案

您的索引和查询必须具有相同的排序规则.

try 此索引,然后再次选中解释:

CREATE INDEX trgm_idx_policy_number_default ON test_policy
    USING gin (policy_number COLLATE "default" gin_trgm_ops);

在ALTER TABLE语句中删除COLLATE,这就是它使用缺省值的原因.就像您的查询中使用的默认设置一样.

Postgresql相关问答推荐

在Go中,如何在没有数据库包的情况下运行PostgreSQL查询?

有没有一种方法可以在参数中添加密码,并在批处理文件中需要时自动获取密码?

无法在kubernetes中设置postgres复制

如何返回old_ids和重复行的映射';来自PostgreSQL函数的s new_id

使用 pgx 扫描范围类型

Postgres 查询指向国外数据工作者的分区表比直接查询 fdw 慢很多倍

gorm 创建并返回值 many2many

postgres 中的模式前缀,被调用元素的范围

从dump文件中恢复三张表遇到的问题

当我写 SELECT ~1;在 Postgresql 上它给了我 -2 结果.这是什么原因?它一直持续〜4和-5等

如何更改几何列的 SRID?

OpenShift:如何从我的 PC 连接到 postgresql

从左连接更新 Postgres

将 Postgres 与 Grails 一起使用

在 Postgresql 中拆分逗号分隔的字段并对所有结果表执行 UNION ALL

如何为 Postgres psql 设置时区?

错误:关系列不存在 PostgreSQL,无法运行插入查询

如何将 Heroku PG 转储导入本地机器

与 iexact 一起使用时,Django get_or_create 无法设置字段

如何在不丢失openproject数据的情况下将postgresql数据库从10升级到12