Query plans not identical for `id in(1,2,3)` and `(id=1 or id=2 or id=3)`

2024-03-09 Thread Ilya Basin
Hi List.

I have a list of bigint keys and I need to retrieve rows by these keys. 
Normally, I would split this list into pages of size 900 and perform several 
`SELECT ... WHERE key in($1,$2,...)`. However, the proprietary ORM we use can 
only produce this SQL: `SELECT ... WHERE (key=$1 or key=$2 or ...)`. 
Surprisingly, PostgreSQL planner treats these two SQLs differently:

- ```select * FROM "audittrail$referencelogline" where id in ( 1 , 2 , 3 )```

Index Scan
https://i.stack.imgur.com/dr8oz.png

- ```select * FROM "audittrail$referencelogline" where id = 1 or id = 2 or id = 
3```

A lot of "Bitmap Index Scan" for each value 
https://i.stack.imgur.com/dnErs.png

Is it possible to configure PostgreSQL 12.16 to treat the second query as the 
first?





Re: Query plans not identical for `id in(1,2,3)` and `(id=1 or id=2 or id=3)`

2024-03-10 Thread Ilya Basin
Laurenz thanks for the info.

Thomas no I can't.

 Original Message 
From: Thomas Kellerer [mailto:sham...@gmx.net]
Sent: Sunday, March 10, 2024 at 11:58 UTC
To: pgsql-general@lists.postgresql.org
Subject: Query plans not identical for `id in(1,2,3)` and `(id=1 or id=2 or 
id=3)`

Ilya Basin schrieb am 09.03.2024 um 20:08:
Hi List.

I have a list of bigint keys and I need to retrieve rows by these keys. 
Normally, I would split this list into pages of size 900 and perform several 
`SELECT ... WHERE key in($1,$2,...)`. However, the proprietary ORM we use can 
only produce this SQL: `SELECT ... WHERE (key=$1 or key=$2 or ...)`. 
Surprisingly, PostgreSQL planner treats these two SQLs differently:

- ```select * FROM "audittrail$referencelogline" where id in ( 1 , 2 , 3 )```

Index Scan
https://i.stack.imgur.com/dr8oz.png

- ```select * FROM "audittrail$referencelogline" where id = 1 or id = 2 or id = 
3```

A lot of "Bitmap Index Scan" for each value
https://i.stack.imgur.com/dnErs.png

Is it possible to configure PostgreSQL 12.16 to treat the second query as the 
first?

Can you convince your obfuscation layer to send an array value (containing all 
IDs) and change the query to:

    select * FROM "audittrail$referencelogline" where id = any(?)








Re: subquery plan rows = 1, but it's merge joined instead of index lookup

2024-04-11 Thread Ilya Basin
Yes! "set join_collapse_limit = 9" was enough to fix the plan, thanks Laurenz.
I will set both to 11.


 Original Message 
From: Laurenz Albe [mailto:laurenz.a...@cybertec.at]
Sent: Thursday, April 11, 2024 at 14:21 UTC
To: ilya Basin; pgsql-general@lists.postgresql.org
Subject: subquery plan rows = 1, but it's merge joined instead of index lookup

On Thu, 2024-04-11 at 15:57 +0300, ilya Basin wrote:
Is there some complexity limit after which the planner starts acting dumb?

Yes, "join_collapse_limit" and "from_collapse_limit".
You can try increasing them.

Yours,
Laurenz Albe