-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 24 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Support for iterating through large result sets
PostPosted: Fri Apr 23, 2004 5:55 pm 
Regular
Regular

Joined: Wed Jan 07, 2004 5:16 pm
Posts: 65
Location: CA, USA
We have a need to be able to process large results sets, of around say 10000 rows.

For smaller result sets we are going to rely on the Pagination support on the Query api (setFirstResults(), setMaxResults() ), but for larger result sets we want to avoid bringing these all into memory.

From what we understand
a) executing a list() against a Query is going to bring back all the rows
b) using iterate() on a Query is going to return an Iterator over a Collection containing just the PK IDs of the matching rows

We want to avoid (a) because we don't want to retrieve such a large result set in memory and second level cache, especially when a typical user is not going to page through all the results anyway.

An alternative to bringing all the results to cache would be to setMaxResults on the initial query to restrict to a more managable size and then issue further paged queries against this limited set to perform the pagination against the values in cache. The SQL that is generated for this uses the rownum() function - our DBAs are telling us that this is also undesirable because DB2 will still return the entire matching result set in order to retrieve the subset that is returned to Hibernate.

Approach (b) is also undesirable because we will have to do 2 queries for every item retrieved. Firstly to return the IDs, secondly to return the actual data.

Our preferred approach would be to use a cursor which would allow us to stream the results as needed from the database. This approach is supported in TopLink (Cursored Stream Support using ScrollableCursors), but it looks like this is not available in Hibernate?

If ScrollableCursors are not supported , is there an alternative approach which would address our concerns?

Thanks,
Kevin Hooke


Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 23, 2004 10:31 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I plan to add a version of Query.scroll() that retrieves whole objects, not just ids. The current implementation of scroll() is probably wrong.

Note, however, that if you customize the Dialect, you can make Hibernate use a scrollable resultset to implement setMaxResults() / setFirstResult(), instead of using the rownum stuff.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 02, 2004 11:47 pm 
Beginner
Beginner

Joined: Mon Sep 15, 2003 12:41 pm
Posts: 21
hi, gavin.

I believe, we need a full-powered wrapper for LIMIT/OFFSET (MySQL),
LIMIT (Postgres), rownum (Oracle), TOP (MSSQL).

What I would like it the built-in syntax in HSQL like OFFSET n LIMIT m,
with using old method (getting old records and filtering them) in case
the DBMS do not support the feature.

Since many, really many applications today have web-based interface,
it crucial to have a pager. And one of the things I've choosen Hibernate
is it's cross-DB nature -- I do not want to bother about SQL dialects any
more.

So, is there any change we will get that functionality soon?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 1:55 am 
Beginner
Beginner

Joined: Sat May 01, 2004 2:44 am
Posts: 32
Location: Brisbane, Australia
gavin wrote:
I plan to add a version of Query.scroll() that retrieves whole objects, not just ids. The current implementation of scroll() is probably wrong.


Doesn't Query.scroll() retrieve whole objects when scrollable result sets are available? Or does it still select ids only first?

Scott


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 3:05 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
It selects just ids in the first query. As I said, I think this is a misfeature and should be changed.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 3:07 am 
Newbie

Joined: Mon May 03, 2004 2:28 am
Posts: 12
Query.scroll() seems to return the same as Query.iterate() i.e. a collection of objects corresponding to the PKs for the query.

I am facing this same issue and Gavin's idea to make Query.scroll() return a collection of objects sounds great.

Please slap me down if I am meandering off-topic but can anyone tell me why Query.iterate() returns a collection of raw Object[] and Query.list() returns a collection of hydrated Objects? If Query.iterate() returned the same as Query.list() then the Query.scroll() enhancement would not be necessary.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 3:09 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
dozen wrote:
I believe, we need a full-powered wrapper for LIMIT/OFFSET (MySQL),
LIMIT (Postgres), rownum (Oracle), TOP (MSSQL).

What I would like it the built-in syntax in HSQL like OFFSET n LIMIT m,
with using old method (getting old records and filtering them) in case
the DBMS do not support the feature.


Negative. We already have exactly this functionality using setMaxResults() / setFirstResult().


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 3:10 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
JerryShea wrote:
can anyone tell me why Query.iterate() returns a collection of raw Object[] and Query.list() returns a collection of hydrated Objects?


eh? what do you mean?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 6:19 am 
Newbie

Joined: Mon May 03, 2004 2:28 am
Posts: 12
Sorry, that was a very poorly explained question.

In the following code fragment is a query (from viewAllAuctionsFast) which creates a new object. If you get the query's list and iterate through it you get the objects but if you iterate though the query's iterator you get an array of the values i.e. item.id,... max(bid.amount) etc.

Code:
Query q = s.createQuery(
"select new AuctionInfo( item.id, item.description, item.ends, max(bid.amount) ) "
+ "from AuctionItem item "
+ "left join item.bids bid "
+ "group by item.id, item.description, item.ends "
+ "order by item.ends desc"
);
AuctionInfo auctionInfo = (AuctionInfo) q.list().iterator().next();
Object[] array = (Object[]) q.iterate().next();


If the query's iterator returned an object then my issue would be gone....


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 6:23 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
oh yeah, you didn't mention "select new()". I agree that we should support "select new" in iterate() and scroll(). its just laziness that we do not.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 11:14 am 
Beginner
Beginner

Joined: Mon Sep 15, 2003 12:41 pm
Posts: 21
gavin wrote:
Negative. We already have exactly this functionality using setMaxResults() / setFirstResult().


Not sure it's the same. It returns IDs. It would be okay when it will
retrieve objects instead, but I have a doubt:

Currently I have a complex query that looks like:

select from
Intersection ti, DomainValue dv1, DomainValue dv2
where
ti=dv1.intersection and
ti=dv2.intersection and
dv1.domain = ? and
dv2.domain = ? and
(dv1.normalizedValue <= ?) and
(dv2.normalizedValue <= ?)
order
by dv1.nvnvp+dv2.nvnvp

(In this query there only two domains; actually there could be
up to 15).

As you see, I get back Object[]. That's because I have to show user
not only the best intersection found, but also the values associated
with the intersection. There are few hundreds of rows usually.
Currently, I just foolishly add "LIMIT N,M" to the query text.
Will Query help me or won't it?

Adding LIMIT into HSQL would make writing queries much simpler,
without need to use Query/Filter, BTW.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 11:30 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
use query.setFirstResult().setMaxResult()


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 7:15 pm 
Newbie

Joined: Mon May 03, 2004 2:28 am
Posts: 12
gavin wrote:
It selects just ids in the first query. As I said, I think this is a misfeature and should be changed.


It would be great if Query.scroll() could return objects but scroll() has at least one limitation: it does not allow polymorphic queries like find() and iterate() do.

Is there any reason why iterate() could not get objects instead of ids? If there's no big reason not to do this I'll start looking into it....


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 7:20 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
It does allow polymorphic queries, just no implicit polymorphism!


I don't know what you think iterate() does different to find() ... the only difference is fetching ids instead of full objects, and I most certainly will not let you change that! It is the whole reason iterate() exists!


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 03, 2004 7:22 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Oh I get it, you wanted to use iterate() to do paging.

Just use setMaxResults(), as is intended. Stop trying to work against the framework, and do things the intended way.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 24 posts ]  Go to page 1, 2  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.