Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select n+1 problem

Foo has Title.
Bar references Foo. I have a collection with Bars.
I need a collection with Foo.Title.

If i have 10 bars in collection, i'll call db 10 times.

bars.Select(x=>x.Foo.Title)

At the moment this (using NHibernate Linq and i don't want to drop it) retrieves Bar collection.

var q = from b in Session.Linq<Bar>()
                where ...
                select b;

I read what Ayende says about this.
Another related question.
A bit of documentation.
And another related blog post.
Maybe this can help?
What about this?
Maybe MultiQuery is what i need? :/

But i still can't 'compile' this in proper solution.

How to avoid select n+1?

like image 609
Arnis Lapsa Avatar asked Oct 05 '09 10:10

Arnis Lapsa


People also ask

What is the N 1 selects problem?

The N+1 query problem happens when the data access framework executed N additional SQL statements to fetch the same data that could have been retrieved when executing the primary SQL query. The larger the value of N, the more queries will be executed, the larger the performance impact.

How do I find and fix N 1 Select Issues in hibernate?

Hibernate N+1 issue occurs when you use `FetchType. LAZY` for your entity associations. Hibernate will perform n-additional queries to load lazily fetched objects. To escape this issue use join fetch, batching or sub select.

What is n plus 1 problem in hibernate?

The N+1 query problem is said to occur when an ORM, like hibernate, executes 1 query to retrieve the parent entity and N queries to retrieve the child entities. As the number of entities in the database increases, the queries being executed separately can easily affect the performance of the application.

What is n1 SQL?

The N+1 query antipattern happens when a query is executed for every result of a previous query. The query count is N + 1, with N being the number of queries for every result of the initial query. If that initial query has one result, N+1 = 2. If it has 1000 results, N+1 = 1001 queries.


1 Answers

This didn't work:

var q = from b in Session.Linq<Bar>().Expand("Foo.Title")
                where ...
                select b;

But this kind a helped:

var q = from b in Session.Linq<Bar>().Expand("Foo")
                where ...
                select b;

..but now thing that's going to use repository does not know that it's loading foos too.
Any ideas how to make it more explicit?

One idea is to change naming to FindBarsWithFoos().

At least it works.

like image 160
Arnis Lapsa Avatar answered Oct 25 '22 11:10

Arnis Lapsa