NHibernate HQL vs CriteriaAPI vs QueryOver vs Linq. Performance

mynkow picture mynkow · Jul 16, 2010 · Viewed 9.2k times · Source

What are the performance differences between the hql and criteriaApi and QueryOver? Are there any situations where one is faster or slower than the other?

Edit: I extended the question with QueryOver and Linq.

=============================================

Well, I am not sure which response to mark as answer so I will mark posts with most VoteUp. I don't know. This is actually more discussion than a question.

Answer

Jaguar picture Jaguar · Jul 16, 2010

The performance characteristics between ICriteria and HQL vary by little (i don't know about QueryOver) for one simple reason.

ICriteria queries will by default try to implement your fetch strategies as defined in your mapping whereas HQL by default considers everything Lazy and depends on your join declarations inside your query to define what is eagerly fetched or not.

Additionally ICriteria depends on mapping for parameter passing whereas HQL allows for explicit parameter types e.g. IQuery.SetInt32("fooParam", 5);

What really matters is the pluggability of ICriteria queries (see ICriteria.CreateCriteria().CreateCriteria() etc) where the NH engine will have to resolve the ICriteria and try to generate the most valid SQL.

In the opposite side its probably easier to predict if an HQL query will produce consistent results and as such makes QueryCache usage easier.

Either way the configuration is generated once with the ISessionFactory creation and mapping definitions and what-not are in-memory, so performance is good.

The actual SQL generation is made differently between the two and that is the reason that a utility for ICriteria -> HQL does not exist.

In the end, my experience has shown me that performance between the 2 is probably the same give or take some milliseconds.

As a side note, declaring as much as possible in the mapping will result in more concise sql generation as well as NHibernate operation, for example for string properties mapping the Length in the .hbm.xml will result in NHibernate checking string lengths before going to the database.