pg.ddx.io  pgsql-performance@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Thomas Kellerer <spam_eater@gmx.net>
To: pgsql-performance@lists.postgresql.org
Subject: Re: Bad query plan when you add many OR conditions
Date: Tue, 14 Jan 2020 09:01:30 +0100
Message-ID: <9748c027-a524-2718-28ec-3c6bc74feafb@gmx.net> (raw)
In-Reply-To: <CAFvCgN5N+C1BZdri5t2gnP15UFNBGtg6Ve0nJ7WALr4XwWYorg@mail.gmail.com>
References: <CAFvCgN5N+C1BZdri5t2gnP15UFNBGtg6Ve0nJ7WALr4XwWYorg@mail.gmail.com>

Marco Colli schrieb am 10.01.2020 um 02:11:
> I have a query on a large table that is very fast (0s):
> https://gist.github.com/collimarco/039412b4fe0dcf39955888f96eff29db#file-fast_query-txt
> 
> Basically the query matches the rows that have a tag1 OR tag2 OR tag3 OR tag4 OR tag5... 
> 
> However if you increase the number of OR at some point PostgreSQL makes the bad decision to change its query plan! And the new plan makes the query terribly slow:
> https://gist.github.com/collimarco/039412b4fe0dcf39955888f96eff29db#file-slow_query-txt
> 
> Instead of this (which is fast):
>   Bitmap Index Scan on index_subscriptions_on_project_id_and_tags
> It starts using this (which is slow):
>   Parallel Index Scan using index_subscriptions_on_project_id_and_created_at
> The choice seems quite stupid since it doesn't have the tags on the new index... and indeed the query takes about 1 minute instead of a few milliseconds. Here's a list of the available indexes:
> https://gist.github.com/collimarco/039412b4fe0dcf39955888f96eff29db#file-_indexes-txt
> 
> How can I encourage PostgreSQL to use the Bitmap Index Scan even when there are many OR conditions? I have tried with VACUUM ANALYZE subscriptions but it doesn't help.
> 
> Note: the query is generated dynamically by customers of a SaaS, so I don't have full control on it

Can you replace the many ORs with a single "overlaps" comparison?

This 

    (tags @> ARRAY['crt:2018_04']::varchar[]) OR (tags @> ARRAY['crt:2018_05']::varchar[]) OR (tags @> ARRAY['crt:2018_06']::varchar[])

is equivalent to 

    tags && array['crt:2018_04','crt:2018_05','crt:2018_06', ...]

The && operator can make use of a GIN index so maybe that uses the index_subscriptions_on_project_id_and_tags regardless of the number of elements.



 







view thread (11+ messages)

Message-ID: <9748c027-a524-2718-28ec-3c6bc74feafb@gmx.net>
Permalink:  ../9748c027-a524-2718-28ec-3c6bc74feafb@gmx.net/
Also on:    postgresql.org/message-id/9748c027-a524-2718-28ec-3c6bc74feafb@gmx.net

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-performance@postgresql.org
  Cc: spam_eater@gmx.net, pgsql-performance@lists.postgresql.org
  Subject: Re: Bad query plan when you add many OR conditions
  In-Reply-To: <9748c027-a524-2718-28ec-3c6bc74feafb@gmx.net>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox