I support a Groovy/Java application that uses Hibernate criteria queries. In one of the queries, it passes in a list of parameters for an IN
clause that can be very long (between 1 and about 8000 items). This actually exceeds Oracle's limits, so we have to break up the list, e.g:
SELECT * from TABLE where ID IN (?, ?, ?, ...) OR IN (?, ?, ?, ...) OR ...
or in criteria-speak (in Groovy):
if (idList) {
Junction orGroup = Restrictions.disjunction()
idList.collate(1000)?.each { subList ->
criteria.add(Restrictions.in('id', subList.collect { it }))
}
criteria.add(orGroup)
}
Having this very long list is ugly and our DBA says the varying number of bind parameters messes with Oracle's ability to optimize query execution and her ability to offer performance tuning suggestions.
I've attempted some obvious ways to reduce the number of bind parameters, such as replacing the list with a subquery that provides the same values, but the performance has always been worse. I suppose it was originally done in this ugly way for performance reasons (but back then, the list couldn't get as large).
The DBA is recommending I try using an "array bind" to pass in the list, which she says will result in an equivalent query with only one bind parameter. Is this possible in Hibernate? She says some other team had success doing that in the past, but doesn't know anything about how to do it on the application side. The queries being built here have a lot of variation based on user input, and I don't have the time to switch away from using Hibernate criteria to build them by hand using something like JDBC.