Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / Databases / November 2006

Tip: Looking for answers? Try searching our database.

select performance

Thread view: 
mehmet.gunacti@gmail.com - 25 Nov 2006 17:17 GMT
there are 2 tables and 2 ValueObjects. customers and orders.

customers
__________
customerID
name
surname
...

orders
______
orderID
FK_customerID
name
price
....

CustomerVO has a collection of OrderVO's.
when writing a method, which retrieves 100 customers which select
method is more appropriate ?

method 1) :
select * from customers c inner join order o on c.customerID =
o.FK_customerID

the result would be something like :

customerID name    orderID price
_________  ____     _____  ____
1                 john      154     200
1                 john      234     300
1                 john      178     355
2                 mike     154     200
2                 mike     433     700

and then in every iteration look if customerID has changed. if so,
construct a new CustomerVO object.

...
int customerID = -1;
while (rs.next()) {
     if (customerID == -1 || rs.getInt("customerID") != customerID) {
          customerVO = new CustomerVO();
          customers.add(customerVO);
          // fill rest of customerVO
     }
     // fill order and put in customer
     OrderVO orderVO = new OrderVO();
     orderVO.setPrice(rs.getDouble("price"));
     customerVO.addOrder(orderVO);
}

method 2)
first retrieve a collection of customers :

select * from customers

then iterate through this collection of customers and get a collection
of orders for every customer.

the second one is much easier to code, but the first one has a much
better performance.

how would Hibernate handle this ?

thanks in advance
Michael Rauscher - 25 Nov 2006 18:43 GMT
mehmet.gunacti@gmail.com schrieb:
> there are 2 tables and 2 ValueObjects. customers and orders.

...

> CustomerVO has a collection of OrderVO's.
> when writing a method, which retrieves 100 customers which select
[quoted text clipped - 3 lines]
> select * from customers c inner join order o on c.customerID =
> o.FK_customerID

..

> method 2)
>
> select * from customers
>
> then iterate through this collection of customers and get a collection
> of orders for every customer.

> how would Hibernate handle this ?

Don't know, but using the first one isn't a good one since you wouldn't
get customers without orders :)

Therefore, there is a method 3:

select * from customers c left join order o on c.customerID =
o.FK_customerID

Bye
Michael
David Harper - 25 Nov 2006 20:33 GMT
> there are 2 tables and 2 ValueObjects. customers and orders.
>
[quoted text clipped - 20 lines]
> select * from customers c inner join order o on c.customerID =
> o.FK_customerID

[SNIP]

> method 2)
> first retrieve a collection of customers :
[quoted text clipped - 3 lines]
> then iterate through this collection of customers and get a collection
> of orders for every customer.

If you're looking to implement an object layer based upon objects
representing customers and orders, then you're more likely to need to
address scenarios which focus on a single customer and his/her orders,
so you will be using method 3:

Your customer gives his name, and you search for his customer ID with a
query such as:

  select customerID from customers where name='John' and surname='Smith'

Then you build a Customer object from this data.

Next, you fetch all of his orders with a query like this:

  select orderID,name,price from orders where FK_customerID=54123

substituting the customer ID from the first query, and build a set of
Order objects from the result set.  You associate the set of orders with
the Customer object, and display/process them as necessary e.g.
generating a web page listing the orders in date order.

Hibernate will take care of all of this for you, of course.

David Harper
Cambridge, England
mehmet.gunacti@gmail.com - 26 Nov 2006 15:53 GMT
of course i agree with method 3 (left outer join instead of inner
join).

> If you're looking to implement an object layer based upon objects
> representing customers and orders,

let's say i would need to list 100 customers with or without orders.

but my question is actually, wouldn't it be a performance loss when
first fetching all customers and afterwards fetching all orders for
each customer.
that would make for 100 customers 101 queries. one for the customers
table and 100 for each customer on orders table.

with method 3, there would be only 1 query. how would hibernate handle
this ? would it calculate the performance overhead and choose and
appropriate method ? btw, i'm very new to hibernate.

David Harper yazdi:
> > there are 2 tables and 2 ValueObjects. customers and orders.
> >
[quoted text clipped - 56 lines]
> David Harper
> Cambridge, England
David Harper - 26 Nov 2006 17:17 GMT
> of course i agree with method 3 (left outer join instead of inner
> join).
[quoted text clipped - 9 lines]
> that would make for 100 customers 101 queries. one for the customers
> table and 100 for each customer on orders table.

If your application really does need to list every (customer,order)
pair, then you are correct, a join between the two tables is the
quickest way to fetch all of the data, especially if there are a lot of
customers and/or orders.

There is one disadvantage, though:  your application must now do more
work when processing the result set, if you wish to group the orders by
customer.  For example, if you want to list all of customer #1's orders
first, then all of customer#2's orders, and so on, then you must (a)
specify customer ID as a column to sort in your SQL query, and (b) write
the loop which processes the result set in such a way that it can detect
when the customer ID changes, which signals that you are now reading a
row which relates to a different customer than the previous row.

I'm afraid that I have no idea how/whether Hibernate handles this
automatically, since I don't use Hibernate :-)

David Harper
Cambridge, England
mehmet.gunacti@gmail.com - 27 Nov 2006 18:10 GMT
thanks, your answer helped. :)

David Harper yazdi:
> > of course i agree with method 3 (left outer join instead of inner
> > join).
[quoted text clipped - 29 lines]
> David Harper
> Cambridge, England
Lionel - 29 Nov 2006 19:26 GMT
> of course i agree with method 3 (left outer join instead of inner
> join).
[quoted text clipped - 13 lines]
> this ? would it calculate the performance overhead and choose and
> appropriate method ? btw, i'm very new to hibernate.

Hibernate will do what you ask it to do ;)

3 possibilities:
1) Look for customers using JOIN fetch mode on orders: 1 query everything is
loaded
2) Look for custormers with a SELECT fetch mode on orders:  101 queries
3) use method 2) but add a batch size=100 on orders: 2 queries, the second
one being select * from orders where customerID=? or customerID=? or .... or
customerID=? (100 "or")

Do performance and memory tests to choose the best method.
It takes 2 seconds to switch between them with hibernate.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.