[jboss-user] [JBoss Seam] - Re: Seam + EJB3 performance

fhh do-not-reply at jboss.com
Tue Jan 30 07:56:27 EST 2007


Just to add some information from the db perspective:

anonymous wrote : 
  | Being impressed by long SQL statements generated by Hibernate and understanding that most of them are not required I decided that I need to try an idea of SFSB as backing bean. I annotated all the relations among entities as fetch=lazy. So all the requests that are generated during page rendering are single select without joins. Tree-related requests are generated only when expanding a node. Thus I don't think that Hibernate or DB is the cause.
  | 

This IS a database problem. A join can be an expensive database operation but that is what RDBMs are made for. A per-row subselect is even worse but if you do a single select for _every_ row you eventually want to fetch you will kill any database.

Why? First of all you have to parse the statements. This is very expensive if your database or JPA provider does not support PreparedStatements (Does Hibernate?). 

Secondly the database will analyze the query to find out which is the most efficient way to fetch the data. If you send 500 single queries instead of one "big" query it will do that 500 times - and will get the wrong result anyway.

If you have a table with 50000 rows with an indexed pk that is fetched lazily in the way you describe then the database will look at the index and read the block which contains the the row indentified by the index for every  single query. Each of this operation is fast but this will happen 50000 times. Since the blocks contains more than one row, blocks will have to be read again and again.

If you do this in one big select, it will just read all the blocks and send it to you. No index is needed and each block is only read once. This is way faster.

So the idea behind lazy loading Lazy loading is not to avoid joins but rather to avoid fetching unneccessary data. Imagine you have an entity relationship between an Entity called "country" which has a collection "citizens". Now your database has all 180 countries and 6,500,000,000 persons.

Now you want to list all countries. If "citizens" was fetched eagerly you would retrieve 6,500,000,000 rows from the database to display information about the 180 countries. This would be ridicolous. If you fetch lazily, you will only get 180 rows at the beginning. The records in the table holding the citizens are only retrieved if they are actually needed.

I hope this explains the concept behind lazy loading.

Regards

Felix




View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4008266#4008266

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4008266



More information about the jboss-user mailing list