The problem is not unique to Orms, although many think it is because it is a common problem, but not inherent to them. And they don’t believe in people’s ability to do wrong manually :).
In the ORM appears more because a naive implementation will force the problem to occur always.
Alias is not only a problem of the ORM itself, but of modeling objects with related data. Either you use a database with a non-relational model, which has its problems there, or you adopt the relational model in the application.
Still you can do something when you mix the two models.
The problem is common when it has an object and other related N, hence the name N + 1 which is the "father" of these N. The problem becomes clear when the query picks up the main data, we will say it is a fiscal note, and then it will pick up the lines of items that make up the note. Picking up data individually in the database can become a very high cost, even more so in the poorly thought out architecture that many people do (some out of necessity).
Generally at least 1 + 1 is required, which is a failure of communication of relational models (not of the model, but of the way with them communicate in the current implementations, what I consider a mistake, and instead of fixing this, they created another worse model, is the history of our area, solve a problem with another problem, but nothing other problem can not solve this too).
By the way, that’s why even some people like to use a Nosql DB like proxy relational. Again, the complexity of the solution increases because the tool has problems easy to solve, but nobody does it.
But in this case if the size is big it won’t be a big problem.
The problem of Eager loading is that you can bring information that you won’t even use. But it depends a lot on the problem, there are cases that this is rare to happen, there are others that even if it happens does not even tickle, and in many cases the fact of coming more than it needs generates a overhead so small that a simple extra consultation will already be worse, ie a 1 + 2 can be worse. Imagine reading a single invoice and it bring all the lines of all tax bills to avoid the N+1, total waste.
This is the problem of automated solutions or programmers who do not understand what they are doing and adopt solutions automatically. The real solution is to understand what will happen in that case and decide what is most interesting. Even manually it is complicated to meet all cases, depends on the query. The ORM may have a mechanism that tries to "guess" which is the best strategy.
In many cases there is a lot of repetition of information by the way it was agreed to work with tabular data, usually it is used the JOIN
.
Most of the time bringing it all at once is usually more interesting than bringing it one by one.
For lack of a better solution would be something like:
SELECT * FROM Nf
SELECT * FROM NfItem
If you have 1000 notes and on average 10 items per note, there will be 11,000 lines in all, with 2 queries, a large and a huge.
As opposed to N+1:
SELECT * FROM Nf
SELECT * FROM NfItem WHERE NfNumero == Nf.Numero
SELECT * FROM NfItem WHERE NfNumero == Nf.Numero
SELECT * FROM NfItem WHERE NfNumero == Nf.Numero
SELECT * FROM NfItem WHERE NfNumero == Nf.Numero
.
.
.
Tantos quantos forem a quantidade de notas fiscais existentes.
I put in the Github for future reference.
Here you will also have 11 thousand lines, but with 1000 small queries and 1 large.
The code is very abstract, just to illustrate.
Try frying one potato fillet at a time and a lot of fillet at once. The first ends quickly individually, but the whole is tragic, the second takes longer, but when it’s over it’s all ready. It’s only a problem if you find out you’ve only sold three fillets, and fried the package.
You make a query to get a list. Then for each element of this list, you make 1 query. That is, N+1 queries. When you release me from a few merge revisions
– Jefferson Quesado
Gavin King, creator of Hibernate once said on the blog that when he is hired to consult/consult on ORM, etc often has to say "In this case we do not use ORM, use a query". ORM is great hand does not serve p/solve 100% of cases. Once upon a time there was a report that was to show only the total number of appointments in the month made by a network of clinics. The ORM had to carry the clinics, the doctors, the patients, the appointments... ended up trying to load all the records of all the tables and after 20 min gave timeout. A query did the same thing in a split second
– jean