13
votes

I hear a lot about performance problems about lazy loading, no matter if at NHibernate, Linq....

The problem is N+1 selects. Example, I want all posts and its users, at foreach I lazy Load Users, them I need one select for posts, plus N select for each user.

Lazy Loading:

1 - select ....from post
N - select ....from user

The "good" approach is do a join:

1 - select .....from post inner join user on post.UserId = user.Id

But seeing EF generated SQL, I realized that a lot of data is wasted. Imagine that all posts are the same User. Inner Join will bring all users columns for each post row.

In performance, which approach is best?

5
This is a good question -- how to choose -- but I think the answer will depend a lot on the data. However, I'd think that you'd be surprised that multiple queries are often worse than "data wasted" by returning more than you need. In other words, there are cases where lazy loading is good, but surprisingly few in "typical" applications. - Dan Rosenstark
Your answer also depends on your ORM, because in the EF, to use your example, these are not the only two options. - Craig Stuntz
@Craig Stuntz Which others options? I am using EF4 - Felipe Pessoto
In EF (any version), you can explicitly load, eager load, or project. In EF 4, you can lazily load, too. IMHO projection is most frequently the right choice, as it allows things which are impossible with any of the other options. - Craig Stuntz
@Craig Stuntz, eager load is "Include()" method, project is "select { post, post.user}", and load is this? "context.LoadProperty(beveragesCategory, c => c.Products);" - Felipe Pessoto

5 Answers

13
votes

Lazy loading is neither good nor bad. See this for a more lengthy explanation:

When should one avoid using NHibernate's lazy-loading feature?

In general, lazy loading is a good default behavior for an ORM, but as an ORM user you need to be conscious of when to override the default and load data eagerly. Profiling the performance of your application is the best way to make decisions about using lazy loading or not using it. Be wary of spending too much effort on premature optimization.

4
votes

The issue with Lazy Loading is being aware of what it is and when it can bite you. You need to be aware of how many potential trips could be made to the database, and how to work around that. I don't view LL as being bad. I just need to be aware of the ramifications of it.

4
votes

Most of my applications involve a service boundary (web service, WCF, etc) and at that point lazy loading at the OR/M is pointless, and implementing lazy loading in your entities that sit on top of your service is kind of a bad idea (the entities now must know about the service).

1
votes

There's no bad and good for lazy loading. You have to decide if you prefer to load resources on run time or application loading times. For example - Real time usually uses a buffer to avoid allocating resources on runtime. That's the opposite of lazy loading and is beneficial for Real Time software.

Lazy loading is beneficial if you have an application that runs for long duration and you don't want to allocate resources on startup.

1
votes

Old thread, but search turned it up so I am adding my two cents. In addition to having to be aware of potential performance issues, the issue of accessing fields after a data context has been disposed stops me from ever using LL now. If you return an instance of an entity from a method where a data context was created and disposed, which is how they are designed to be used, accessing those virtual fields will exception fault. The solutions to this are to either include the fields in the queries (i.e. .Include), never return entity classes from your data layer/service, or keep data contexts alive for much longer. Including the fields is the best option, and that is just as easy without lazy loading enabled.