What is the best way to boost NHibernate performance?

I have an application that uses NHibernate as its ORM, and sometimes it experiences performance issues due to the way the data accesses them. What can be done to improve NHibernate performance? (Please limit one recommendation per answer)

+58
performance orm nhibernate data-access-layer
Sep 15 '08 at 21:22
source share
12 answers

The first and most dramatic performance issue you may encounter with NHibernate is to create a new factory session for each session you create. Only one factory session must be created for each application execution, and all sessions must be created using the factory.

Along these lines, you should continue to use the same session, if that makes sense. It depends on the application, but for most web applications it is recommended to use one session for each request. If you often give up your session, you do not get the benefits of your cache. Intelligent use of the session cache can change the procedure with a linear (or worse) number of requests for a constant number without much work.

Equally important, you want to make sure you're lazy loading object references. If you do not, all graph objects can be loaded even for the simplest queries. There are only certain reasons not to do this, but it is always best to start with lazy loading and switch as needed.

This leads us to impatient collection, the opposite of lazy loading. When you move the hierarchy of objects or traverse collections, you can easily lose information about how many queries you make, and you get an exponential number of queries. Easy fetching can be done on request based on a FETCH JOIN request. In rare cases, for example, if there is a certain pair of tables, you always choose a connection, consider abandoning lazy loading for these relationships.

As always, SQL Profiler is a great way to find queries that are slow or run repeatedly. At my last job, we had a development function that also took into account page requests. A large number of requests for a subroutine is the most obvious indicator that your program does not work with NHibernate. If the number of queries per routine or query looks good, perhaps you will configure the database settings; make sure you have enough memory to store execution plans and data in the cache, properly index your data, etc.

One tricky issue we are facing is SetParameterList (). The function makes it easy to pass a list of parameters to the request. NHibernate implemented this by creating one parameter for each element passed. This leads to a different tariff plan for each number of parameters. Our execution plans almost always came out of the cache. In addition, numerous parameters can significantly slow down the request. We performed the usual NHibernate hacking to send items as a delimited list in one parameter. The list was split in SQL Server by the table value function, which our hack automatically inserted into the IN clause of the query. There may be other land mines depending on your application. SQL Profiler is the best way to find them.

+48
Sep 15 '08 at 22:03
source share

NHibernate SessionFactory is an expensive operation, so creating a Singleton is a good strategy, which ensures that there is only one SessionFactory instance in memory:

public class NHibernateSessionManager { private readonly ISessionFactory _sessionFactory; public static readonly NHibernateSessionManager Instance = new NHibernateSessionManager(); private NHibernateSessionManager() { if (_sessionFactory == null) { System.Diagnostics.Debug.WriteLine("Factory was null - creating one"); _sessionFactory = (new Configuration().Configure().BuildSessionFactory()); } } public ISession GetSession() { return _sessionFactory.OpenSession(); } public void Initialize() { ISession disposeMe = Instance.GetSession(); } } 

Then in your Global.Asax Application_Startup application you can initialize it:

 protected void Application_Start() { NHibernateSessionManager.Instance.Initialize(); } 
+25
Oct 26 '08 at 23:27
source share

Avoid and / or decrease, select problem N + 1 , knowing when to switch from lazy loading to the desired selection for slow queries.

+11
Dec 02 '08 at 20:03
source share

There is no recommendation, but a tool to help you: NH Prof ( http://nhprof.com/ ) seems promising, it can evaluate your use of the ORM structure. This may be a good starting point for your NHibernate setup.

+10
02 Feb '09 at 19:00
source share

Without any specific features of the performance problems that you see, I can only offer a generalization. In my experience, most database query performance problems arise due to the lack of proper indexes. So my suggestion for the first action is to check your query plans for non-indexed queries.

+4
Sep 15 '08 at 21:40
source share

NHibernate generates fairly fast SQL right out of the box. I have been using it for a year and I don’t have to write SQL with it yet. All my performance problems were from Normalization and lack of indexes.

The easiest fix is ​​to check your query execution plans and create the appropriate indexes, especially in the foreign key columns. If you are using Microsoft SQL Server, the Database Engine Tuning Advisor is a great help.

+3
Sep 19 '08 at 1:02
source share

"Only one recommendation per answer"? Then I would go for this:

Avoid combining duplicates (AKA Cartesian products) due to joining two or more associations with many others; use Exists subqueries, MultiQueries, or FetchMode instead of subselect.

Taken With: Hibernate Performance Tuning Tips

+3
Nov 07 2018-11-11T00:
source share

If you are not already using lazy loading (respectively), run. Purchasing collections when you don't need them is a waste of everything.

The chapter Improving Performance describes this and other ways to improve performance.

+1
Sep 19 '08 at 22:37
source share

Profiling is the first step β€” even simple temporary unit tests β€” to figure out where you can get the most gain.

For collections, consider setting up batch size to reduce the number of select statements to be exposed - see Improving Performance for Details

+1
Sep 23 '08 at 8:52
source share

Am I allowed to limit my answer to one option? In this case, I would choose that you implement the second level caching mechanism in NHibernate.

Thus, for each object in your mapping file, you can define a cache strategy. The second-level cache will store the objects that have already been extracted in memory and, therefore, will not make another return path to the database. This is a huge performance booster.

Your goal is to identify objects that are constantly accessing your application. Among them will be general settings, etc.

There is a lot of information for the nhibernate second level cache and how to implement it.

Good luck :)

+1
Sep 23 '08 at 21:24
source share

Caching, caching, caching - Do you use the first level cache correctly [closing sessions prematurely or using StatelessSession to bypass first level caching]? Do you need to set up a simple second level cache for values ​​that change infrequently? Can you cache query result sets to speed up queries that change infrequently?

[Also configuration - can you set elements as immutable? Can you restructure your queries to return only the necessary information and convert them to the original object? Will Batman be able to stop Riddler before he gets to the dam? ... oh, sorry, carried away.]

+1
Oct 09 '08 at 14:58
source share

What the multisolar said.

Read Chapter 19 of the Productivity Improvement Documentation.
NHibernate: http://nhibernate.info/doc/nhibernate-reference/performance.html
Hibernate: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

Use SQL Profiler (or the equivalent for your database) to search for long-term queries. Optimize these queries with appropriate indexes.

For database calls used on almost every page of an application, use CreateMultiQuery to return multiple result sets from a single database query.

And, of course, cache. OutputCache directive for pages / controls. NHibernate caching for data.

0
Aug 12 '09 at 21:51
source share



All Articles