-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add full support for fetch size in JPA #696
Comments
In my Java performance trainings, I explain the working of jdbc fetch size. And people then ask: why is it so difficult in JPA? And I don't have an answer.. |
Correct me if I'm wrong, but is it the case that essentially every JDBC driver except for Oracle defaults to retrieving all rows (which is typically the right thing for JPA), but that Oracle has an absurdly low default fetch size of 10? |
Oh, from my experiments it looks like SQL Server defaults to 128. |
So I guess my question in return is: why doesn't it work to just set this globally using |
Good question. The thing is, in case you don't need all the result rows, you are over-allocating memory and over-fetching rows. And with that setting, you do that for all the queries in your app/service. Say, you do pagination by the user of 25 rows on a page, this can be implemented in Hibernate nicely and efficiently with:
This will be quick. In case of thousands of rows, and a very large fetch size, the first page will take much longer to load and unnecessarily with wasteful processing, in case the user just chooses to see one page. We have documented that here: too-many-returned-rows-or-roundtrips (feedback welcome) |
Well, no, that's not right.
Essentially, in any multi-user system, we almost always want to avoid leaving resources open on the database side after we return from a round trip.
Nononononononnonono that's not how pagination works at all! We use |
AFAICT, this is only true for Oracle, FTR.
Nonononono that's just not right.
You do not, ever need to set a fetch size when calling
No, that's bad advice except in very special cases. The only case I can think of where this advice is correct is if you're using |
Look, if were so important to futz about directly with the fetch size for every query, there's no way that JPA would have made it through 20 years of existence without us adding it and without anyone even opening a feature request for it until now. I'm not saying "no" to the feature, because, well, Hibernate has it obviously, and even though it's not much used, I'm sure the need for it arises occasionally. (Apparently we use it in Hibernate Search for batch processing entities, for example.) But it sounds like all you need is to set |
Thanks for the feedback! Clarifying, I will update the documentation. For Wouldn't the implementation be improved by using |
It would have to be a pretty massive result set before you would get an OOME! And how is setting the JDBC fetch size going to help with that? Hibernate is still going to eagerly read all the rows from the database, because Hibernate doesn't know until after it's materialized the whole object graph that you have more than one root entity in it.
That would break any query which fetches a collection. In principle we could append an unnecessary If you want to call |
Look, honestly, it really looks to me like you're overthinking this. People get into trouble when they think they can do something better/different to what has already been working perfectly well in millions of programs for more than two decades. |
Okay, thanks for your remarks.
Do you agree? |
Yep, exactly. (None of that means we shouldn't provide a |
Ah, that's a quick response :-) I just updated it. |
Note that DB2 jdbc driver seems to have a default fetch size of 32. |
How did you determine this? On Db2 LUW, |
Good point, I am actually confused. I found 32 here:
https://community.jaspersoft.com/knowledgebase/best-practices/jdbc-fetch-size-affecting-adhoc-sample-data/
And
https://venkatsadasivam.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/
But a good source says unlimited:
https://vladmihalcea.com/resultset-statement-fetching-with-jdbc-and-hibernate/
And in recent performance tests we did with db2 on mainframe, setting it to
200 improved the query performance significantly.
Op do 16 jan 2025, 16:45 schreef Gavin King ***@***.***>:
… Note that DB2 jdbc driver seems to have a default fetch size of 32.
How did you determine this?
On Db2 LUW, Statement.getFetchSize(), PreparedStatement.getFetchSize(),
and ResultSet.getFetchSize() all return 0 for me.
—
Reply to this email directly, view it on GitHub
<#696 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AF3TVWYOTA5NXHG5XEZLMDT2K7HXLAVCNFSM6AAAAABVFWJZHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOJWGA3DSMJUGI>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
And this advice seems strange if the default fetch size is unlimited:
https://www.ibm.com/docs/en/iis/11.7?topic=optimization-fetch-size-values
Op do 16 jan 2025, 17:30 schreef Jeroen Borgers ***@***.***>:
… Good point, I am actually confused. I found 32 here:
https://community.jaspersoft.com/knowledgebase/best-practices/jdbc-fetch-size-affecting-adhoc-sample-data/
And
https://venkatsadasivam.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/
But a good source says unlimited:
https://vladmihalcea.com/resultset-statement-fetching-with-jdbc-and-hibernate/
And in recent performance tests we did with db2 on mainframe, setting it
to 200 improved the query performance significantly.
Op do 16 jan 2025, 16:45 schreef Gavin King ***@***.***>:
> Note that DB2 jdbc driver seems to have a default fetch size of 32.
>
> How did you determine this?
>
> On Db2 LUW, Statement.getFetchSize(), PreparedStatement.getFetchSize(),
> and ResultSet.getFetchSize() all return 0 for me.
>
> —
> Reply to this email directly, view it on GitHub
> <#696 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AF3TVWYOTA5NXHG5XEZLMDT2K7HXLAVCNFSM6AAAAABVFWJZHWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKOJWGA3DSMJUGI>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
I mean, these are just some blogs from > 10 years ago. People post wrong information on blogs all the time.
Yeah, well, again, I'm not sure, because that's a different product to Db2 LUW, so perhaps the defaults are different.
That's the documentation for InfoSphere Information Server you linked to. I have no idea what InfoSphere Information Server is, but I don't think it's Db2. I think I'm going to just assume that the Db2 JDBC driver isn't lying to me and that the default is indeed 0 i.e. unlimited at least on LUW. |
That sounds like a reasonable assumption :-) DB2 on mainframe may be different indeed; with the app and db2 on the same LPAR, roundtrips are much cheaper than usual, on Linux. |
Maybe it is a good idea to collect very common options like fetchsize, batchsize, batchtype (IN, JOIN, Subquery, EXISTS etc.), cache size etc. and make them a part of the API. |
As a Java performance tuner, I like to have full fetch size support in JPA, just like Hibernate API offers with:
Query setFetchSize(int fetchSize)
Obviously, for thousands of rows, fetching all in one round trip in stead of 10 at a time is much faster.
The current way with a hint is lousy and difficult to use. Gavin agrees that is sucks;-)
The text was updated successfully, but these errors were encountered: