Reputation: 948
I want JOOQ to generate ... in (?)
and bind list as an array parameter (Postgres). My code looks like
.where(
Tables.TABLE.FIELD.in(idsList)
)
in (?, ?, ?, ?, ...)
Upvotes: 5
Views: 4992
Reputation: 220762
How can I do this?
You can use the DSL.any(T[])
operator, e.g.
TABLE.FIELD.eq(any(1, 2, 3))
This will bind only one array variable to the JDBC statement
Why it's not done by default since it's more efficient that generation (and parsing by PG) of the string
It might be worth thinking about a flag in Settings
. I've registered a feature request for this: https://github.com/jOOQ/jOOQ/issues/6029
In general, jOOQ allows users to write exactly the SQL they want to send to the database server, so the automatic "optimisation" and rewriting of SQL might appear quite unexpected to some users. This is just a general rule of thumb in jOOQ. It's always worth thinking about optimisations and making them opt-in through Settings
.
However, it's always important to actually measure these things. While there is certainly a bit less of a parsing and SQL generation overhead with your suggested approach, beware that an array's cardinality may be much harder to estimate correctly than a hard-wired IN
list. Using an array for small lists can have negative effects on your execution plan. So, the few microseconds you're saving on the parser side will weigh against the few milliseconds (?) at the execution side!
I've benchmarked this in the following blog post: https://blog.jooq.org/sql-in-predicate-with-in-list-or-with-array-which-is-faster/
The IN
list seems to consistently outperform the array version (in my specific benchmark case) until a length of around 50
Upvotes: 7