In any application that needs database interaction, DB operations are the key to the application performance. Most of the application performance problems come because the sqls being executed are not optimized or there are huge numbers of queries being executed or there is too much data getting loaded by the query or the columns are not properly indexed or there is no caching being done and the application always hits the DB. In this series, I will try to cover different strategies that you need to use for a good performing ORM based application.
As we all know, the fundamental strategy to tune an application performance is to optimize the sql queries. As a general practice, object retrieval using many round trips to the database is avoided and you would fetch all the required data for a particular operation using a single SQL query using Joins to retrieve related entities. Also, you would fetch only the data that is required i.e data will not be fetched unnecessarily if it is not needed so as to reduce the load on the DB. However this becomes an issue when you use ORM because you no longer write the SQL queries yourself and queries are generated and executed by the underlying ORM engine.
Thankfully ORM engine like Hibernate provides various hooks to optimize the sql as well no of trips that will be made to the database. The most important of these hooks is “fetching strategy” which defines what data will be fetched, when and how.
There are four fetching strategies for loading an object and its associations. (We will use Department-Employee relationship for all the explanation)
- Immediate fetching : In this strategy, the associated object is fetched immediately after the owning entity is fetched, either from the database using a separate SQL query or from the seconadary cache. This is usually not an efficient strategy unless the associated object is cached in the secondary cache or when separate queries are more efficient than a Join query. You can define this strategy by setting lazy=”false” and fetch=”select” for the relationship property definition in the CFC.example :
<cfproperty name="employees" fieldtype="one-to-many" cfc="employee" fkcolumn="deptId" lazy="false" fetch="select">
With this strategy, on loading the department object, its employees object will be loaded immediately using a separate SQL query. As a result, this strategy is extremely vulnerable to ‘N+1 Select problem’.
pros : The association is loaded immediately and hence the associated object can be accessed even after the ORM session is closed.
cons : A large number of sqls get executed causing a higher traffic between application and the database. The association is loaded even if it might not be needed.When to use : When the association is almost always read after loading the object and executing separate sql is more efficient than executing a join query.
- Lazy fetching : In this strategy, the associated object or collection is fetched lazily i.e only when required. For example, when you load a Department object, all the associated employees will not be loaded at all. It will be loaded only when you access it. This results in a new request to the database but it controls how much of data is loaded and when is it loaded. This helps in reducing the database load because you fetch only the data that is required and is a good default strategy. We will talk about this in much more detail in the next post. For the time being lets just say this is the most commonly used and the default strategy for obvious reasons. You can define this strategy by setting lazy=”true” or lazy=”extra”.
example :<cfproperty name="employees" fieldtype="one-to-many" cfc="employee" fkcolumn="deptId" lazy="true" >
pros : Only the minimum required data is loaded. This avoids loading of entire object graph in memory and hence the performance is generally good.
cons : If the association is always accessed after loading, this would result in extra sql execution. If the loaded object is accessed in another ORM session (i.e has become detached), extra care must be taken to avoid errors like ‘LazyInitializationException’ or ‘NonUniqueObjectException’.When to use : When the association is not immediately read after loading the object. This is the most commonly used and default strategy.
- Eager fetching : In this strategy, the associated object or collection is fetched together with the owning entity using a single SQL Join query. Thus, this strategy reduces the number of trips to the database and is a good optimization when you always access the associated object immediately after loading the owning entity. You can define this strategy by setting fetch=”join” for the relationship property definition in the CFC.example :
<cfproperty name="employees" fieldtype="one-to-many" cfc="employee" fkcolumn="deptId" fetch="join">
With this strategy, on loading the department object, both department and employees data will be fetched from the database using a single join query.
Even if the eager fetching is not defined in the CFC metadata, it can be done at runtime using ORMExecuteQuery. This can be very powerful in scenarios where in most of the cases, you choose the assocition to be lazily loaded but in some cases, you want to immediately load it. In those case, use Join in the HQL and execute that using ORMExecuteQuery.
Example :
ORMExecuteQuery("from Department dept left join fetch dept.employees") ORMExecuteQuery("from Department dept left join fetch dept.employees where dept.id=1001")pros : The association is loaded immediately and hence the associated object can be accessed even after the ORM session is closed. The association is loaded using a single join query which usually is more efficient than executing multiple queries.
cons : The association is loaded even if it might not be needed. Since the query used is a join query, the resultset returned by the DB will typically contain lot of repititive data. If used for more than one collection of an entity, this will create a cartesian product of the collection’s data and thus causing creation of a huge resultset.When to use : When the association is almost always read after loading the object. More suitable for many-to-one and one-to-one association or single collection where the associated objects can be loaded using join query without much overhead.
- Batch fetching : This strategy tells Hibernate to optimize the second SQL select in Immediate fetching or lazy fetching to load batch of objects or collections in a single query. This allows you to load a batch of proxied objects or unitialized collections that are referenced in the current request. This is a blind-guess optimization technique but very useful in nested tree loading.
The concept of batch-fetching is slightly confusing (at least I got confused when I first read about it). So you need to pay careful attention to this.
This can be specified using “batch-size” attribute for CFC or relationship property. There are two ways you can tune batch fetching: on the CFC and on the collection.- Batch fetching at CFC level : This allows batch fetching of the proxied objects and hence is applied to one-to-one and many-to-one relationship. To give an example, cosider Employee-Department example where there are 25 employee instance loaded in the request(ORM session). Each employee has a reference to the department and the relationship is lazy. Therefore employee objects will contain the proxied object for Department.If you now iterate through all the employees and call getDepartment() on each, by default 25 SELECT statements will be executed to retrieve the proxied owners, one for each Department proxy object. This can be batched by specifying the ‘batch-size’ attribute on the Department CFC like
<cfcomponent table=”Department” batch-size=”10″ …>
When you call getDepartment() on the first employee object, it will see that department should be batch fetched, and hence it will fetch 10 department objects that are proxied in the current request.
So for 25 employee objects, this will make Hibernate to execute at max three queries – in batch of 10, 10 and 5.
You must note that batch-size at component level does not mean that whenever you load a Department object, 10 department objects will get loaded in the session. It just means that if there are proxied instances of Department object in the session, 10 of those proxied objects will get loaded together. - Batch fetching at collections : This allows batch fetching of value collections, one-to-many or many-to-many relationships that are unitialized. To give an example, consider Department-Employee one-to-many relationship where there are 25 departments loaded and each department has a lazy collection of employees. If you now iterate through the departments and call getEmployees() on each, by default 25 SELECT statements will be executed, one for each Department to load its employee objects. This can be optimized by enabling batch fetching which is done by specifying “batch-size” on the relationship property like
In Department.cfc :
<cfproperty name="employees" fieldtype="one-to-many" cfc="employee" fkcolumn="deptId" lazy="true" batch-size="10">
One important thing to understand here is that batch-size here does not mean that 10 employees will be loaded at one time for a department. it actually means that 10 employee collections (i.e employees for 10 department objects) will be loaded together.
When you call getEmployees() on the first department, employees for 9 other departments will also be fetched along with the one that was asked for.
The value for batch-size attribute should be chosen based on the expected number of proxied objects or unitialized collections in the session.
- Batch fetching at CFC level : This allows batch fetching of the proxied objects and hence is applied to one-to-one and many-to-one relationship. To give an example, cosider Employee-Department example where there are 25 employee instance loaded in the request(ORM session). Each employee has a reference to the department and the relationship is lazy. Therefore employee objects will contain the proxied object for Department.If you now iterate through all the employees and call getDepartment() on each, by default 25 SELECT statements will be executed to retrieve the proxied owners, one for each Department proxy object. This can be batched by specifying the ‘batch-size’ attribute on the Department CFC like

#1 by cupolas on September 22nd, 2011
| Quote
You really know your stuff bro. Liker serious
#2 by admin on September 23rd, 2011
| Quote
thanks for this posting, i like it
#3 by Jason on September 23rd, 2011
| Quote
I was very encouraged to find this site. I wanted to thank you for this special read. I definitely savored every little bit of it and I have you bookmarked to check out new stuff you post.
#4 by coffee store on September 25th, 2011
| Quote
Great post. This is what i’ve been looking for.
thanks for share,,
#5 by harrypotter halloween costumes on September 25th, 2011
| Quote
Finnaly i found the information i want.Thanks bro
#6 by auto car used on September 25th, 2011
| Quote
nice article…
thanks for share
#7 by home metro on September 25th, 2011
| Quote
good job guys…
i have bookmark
visit my other site:
home reference
#8 by Info Lowongan Kerja Terbaru on September 25th, 2011
| Quote
Finnaly i found the information i want.Thanks bro
i like your article
#9 by james on September 26th, 2011
| Quote
thanks very much, I want to understand this
#10 by koi fish Information on October 2nd, 2011
| Quote
I think I must say thank you for this information,,,very deep thanks
Trackback: Blogger Nusantara Blogpreneur Indonesia
#11 by Knjigovodstvena Agencija on October 5th, 2011
| Quote
Great article, man! I have been searching these information for a log time.
#12 by Gaptek Update on October 7th, 2011
| Quote
i need to study this more. would you help me ? thanks for your introduction.
#13 by Farley on October 9th, 2011
| Quote
was very encouraged to find this reference. I wanted to thank you for this special read.
#14 by Blogger nusantara blogpreneur indonesia on October 11th, 2011
| Quote
support me to win a semi seo contest. plz visit n leave your comment at my post. thanks.
#15 by basketball on October 14th, 2011
| Quote
I’m enjoyed reading this article and whole website, thanks a lot for this informations!
#16 by VPS Technology Blog on October 15th, 2011
| Quote
Thanks for the info dude
#17 by Technology Solutions on October 15th, 2011
| Quote
Awesome share, thanks bro
#18 by glass chandeliers on October 15th, 2011
| Quote
When you create a multiple document interface, forms-based program, your application should be able to support multiple instances of a similar form. Is that true?
#19 by Jasa Consultant on October 16th, 2011
| Quote
thank you very much for this great post. heflpfull with us
#20 by ponkster on October 24th, 2011
| Quote
frankly i hates coldfusion.. but i expect information as many as i want about programming, at least i have new idea about my further works. thanks dude, it was nice post
#21 by SoccerTime on October 29th, 2011
| Quote
Здравствуйте!
Зацените наш новый футбольный сайт http://www.soccertime.ru.
На сайте вы можете ознакомиться футбольные новости, информацию о стадионах и игроках.
#22 by uzank on November 2nd, 2011
| Quote
nice posting, i like it!
#23 by Icah on November 11th, 2011
| Quote
plz allow me to comment on your post. i really need some backlink from high pr blog like yours. thanks mwaach
#24 by Taiguegen on November 12th, 2011
| Quote
Hi! i’m Re-twit you post: to my @niuuaoui twitter
Trackback: Century 21 Broker Properti Jual Beli Sewa Rumah Indonesia
Trackback: Century 21 Broker Properti Jual Beli Sewa Rumah Indonesia
#25 by my7 review on December 12th, 2011
| Quote
forms-based program, your application should be able to support multiple instances
#26 by propolis on December 12th, 2011
| Quote
i think This strategy tells Hibernate to optimize the second SQL
#27 by seo optimizacija on December 13th, 2011
| Quote
Excellent post. I want to thank you for this informative read. I will bookmark this site and visit again…
#28 by hdr cx160 on December 14th, 2011
| Quote
Hi, Neat post. There’s an issue with your website in internet explorer, may test this? IE nonetheless is the market chief and a good element of folks will pass over your fantastic writing because of this problem.
#29 by kako napraviti web stranicu on December 16th, 2011
| Quote
I’m so excited. I really appreciate sharing this great post. Keep up your excellent work.
#30 by hypnosis on December 19th, 2011
| Quote
Hey, thanks for the informative post. Was a nice share!
#31 by film art on December 20th, 2011
| Quote
I want to thank you for this informative read. Loved the whole article! Thanks for sharing.
#32 by get wife give bj on December 28th, 2011
| Quote
It is very informative. I will bookmark this site and visit again. Keep up your excellent work.
#33 by Croatia pictures on December 29th, 2011
| Quote
Very good post .Keep up your excellent work
#34 by Solar panels info on December 29th, 2011
| Quote
your application should be able to support multiple instances
#35 by vidi ovo on January 7th, 2012
| Quote
It is very informative. Loved the whole article! Thanks for sharing.
#36 by Berita Unik Terbaru on January 8th, 2012
| Quote
There are lots of comments that are very useful to everyone. I will be back tommorow to read your new post.
#37 by Kocim News on January 8th, 2012
| Quote
I am so proud to met this blog thanks for the comments and important information.
#38 by tourist playground on January 8th, 2012
| Quote
I want to thank you for this informative read. Loved the whole article! Thanks for sharing.
#39 by Birthday quotes For Brothers on January 9th, 2012
| Quote
ColdFusion ORM : Performance tuning – Fetching Strategy | ColdFused? I was suggested this blog by my cousin. I’m not sure whether this post is written by him as no one else know such detailed about my difficulty. You’re wonderful! Thanks! your article about ColdFusion ORM : Performance tuning – Fetching Strategy | ColdFused? Best Regards Andy Andy
#40 by kese on January 16th, 2012
| Quote
Very good post .Keep up your excellent work
#41 by Numerologija on January 25th, 2012
| Quote
Amazing post, very informative and quality. Cheers
#42 by Filmovi sa prevodom online on January 26th, 2012
| Quote
Great article. Keep up
#43 by Raton about asteroids Laura on January 31st, 2012
| Quote
Hmm..The fetching strategy you say.Ok! I will try it!