简体   繁体   English

为什么此查询在JSONB Gin索引字段上花费这么长时间? 我可以修复它以便它实际使用索引吗?

[英]Why is this query taking so long on JSONB Gin index field? Can I fix it so it actually uses the index?

Recently we changed the format of one of our tables from using a single entry in a column to having a JSONB column in the format of ["key1","key2","key3"] etc. Although we built a GIN index on the JSONB field the queries that we use on it are EXTREMELY slow (in the range of 50 minutes in explain plan). 最近,我们将其中一个表的格式从使用列中的单个条目更改为使用[“ key1”,“ key2”,“ key3”]]等格式的JSONB列。尽管我们在JSONB字段对我们使用的查询速度极慢(在解释计划中为50分钟)。 I am trying to find out a way to optimize the query and to correctly utilize the index. 我试图找到一种方法来优化查询并正确利用索引。 I pasted the query below as well as the explain plan for it. 我在下面粘贴了查询及其解释计划。 The indexed fields are visit.visitor, launch.campaign_key, launch.launch_key, visit.store_key and visits.stop JSONB field as GIN index. 索引字段为visit.visitor,launch.campaign_key,launch.launch_key,visit.store_key和visits.stop JSONB字段(作为GIN索引)。 We are using PostgresQL 9.4 我们正在使用PostgresQL 9.4

explain (analyze on) select count(subselect.visitors) as visitors,
subselect.campaign as campaign 
from (
    select distinct visit.visitor as visitors,
          launch.campaign_key as campaign 
from visit 
    join launch on (jsonb_exists(visit.stops, launch.launch_key)) where 
       visit.store_key = 'ahBzfmdlYXJsYXVuY2gtaHVi' 
       and launch.state = 'PRODUCTION') as subselect group by subselect.campaign

Explain results: 说明结果:

HashAggregate  (cost=63873548.47..63873550.47 rows=200 width=88) (actual time=248617.348..248617.365 rows=58 loops=1)
  Group Key: launch.campaign_key
  ->  HashAggregate  (cost=63519670.22..63661221.52 rows=14155130 width=88) (actual time=248587.320..248616.558 rows=1938 loops=1)
    Group Key: visit.visitor, launch.campaign_key
    ->  HashAggregate  (cost=63307343.27..63448894.57 rows=14155130 width=88) (actual time=248553.278..248584.868 rows=1938 loops=1)
          Group Key: visit.visitor, launch.campaign_key
          ->  Nested Loop  (cost=4903.09..56997885.96 rows=1261891461 width=88) (actual time=180648.410..248550.249 rows=2085 loops=1)
                Join Filter: jsonb_exists(visit.stops, (launch.launch_key)::text)
                Rows Removed by Join Filter: 624114512
                ->  Bitmap Heap Scan on launch  (cost=3213.19..126084.38 rows=169389 width=123) (actual time=32.082..317.561 rows=166121 loops=1)
                      Recheck Cond: ((state)::text = 'PRODUCTION'::text)
                      Heap Blocks: exact=56635
                      ->  Bitmap Index Scan on launch_state_idx  (cost=0.00..3170.85 rows=169389 width=0) (actual time=21.172..21.172 rows=166121 loops=1)
                            Index Cond: ((state)::text = 'PRODUCTION'::text)
                ->  Materialize  (cost=1689.89..86736.04 rows=22349 width=117) (actual time=0.000..0.487 rows=3757 loops=166121)
                      ->  Bitmap Heap Scan on visit  (cost=1689.89..86624.29 rows=22349 width=117) (actual time=1.324..14.381 rows=3757 loops=1)
                            Recheck Cond: ((store_key)::text = 'ahBzfmdlYXJsYXVuY2gtaHVicg8LEgVTdG9yZRinzbKcDQw'::text)
                            Heap Blocks: exact=3672
                            ->  Bitmap Index Scan on visit_store_key_idx  (cost=0.00..1684.31 rows=22349 width=0) (actual time=0.780..0.780 rows=3757 loops=1)
                                  Index Cond: ((store_key)::text = 'ahBzfmdlYXJsYXVuY2gtaHVicg8LEgVTdG9yZRinzbKcDQw'::text)
Planning time: 0.232 ms
Execution time: 248708.088 ms

I should mention the index on stops is built CREATE INDEX ON visit USING GIN (stops) 我应该提到停靠站索引是使用CINATE INDEX访问时使用的GIN(停靠站)

I'm wondering if switching to building it to CREATE INDEX ON visit USING GIN (stops->'value') 我想知道是否在访问时使用GIN转换为建立CREATE INDEX(止损->“值”)

Will resolve the issue? 会解决问题吗?

The wrapper function jsonb_exists() prevents the use of the gin index on visits.stops . 包装函数jsonb_exists()可防止使用上的杜松子酒索引的visits.stops Instead of 代替

from visit 
join launch on (jsonb_exists(visit.stops, launch.launch_key))

try 尝试

from visit 
join launch on visit.stops ? launch.launch_key::text

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM