4 ms·
I see - so in your case you gain from the fact that many of the joins are likely to result in zero matches. And since you're joining on a nullable FK, you can
by Mouse47 9y ago
I see - so in your case you gain from the fact that many of the joins are likely to result in zero matches. And since you're joining on a nullable FK, you can tell in advance whether the record exists without a lookup - I ran a test and I verified that you pay a cost for the below join regardless of whether the FK column is null.
select *
from Person p1
--p1.Spouse is null for the record in question
join Person p2 on p1.Spouse = p2.PersonId
where p1.PersonId = 42
(I understand why it can't do it in the execution plan, but I'm surprised it doesn't 'short-circuit' at runtime since the join predicate is trivially unsatisfiable for that row)
Your other benefit involves conditionally needing data. I will say it's not too hard to structure app code to avoid loading redundant/unneeded data in your email example, but it's certainly easier and more maintainable when property access is fundamentally linked to its actual retrieval - it's impossible for another developer to make changes to your version and 'lose' the efficiency, while the same isn't true for mine.
So it's less black and white than I thought...which it usually is :)
How do you feel about using 'explicit' lazy loading? E.g.
PersonEntity person;
if(IWantToSendEmail){
person.Reference(x=>x.Email).Load();
//use email info here
}
This might be the best of both worlds...
- mattmanser 9y agoIt actually is quite hard to do it and have re-usable code. There are various different ways the same email might get triggered, maybe the booking came from an API call, maybe it came from a new booking form, maybe it came from a 'send reminder' button. In all cases, I have a booking object that will be in a different state of being filled in. The underlying need for data for the rest of the request is very different. Some of them need a fully filled in booking, some of them need the bare essentials. Our "fully load this booking" function takes like 150ms, which isn't cheap and a significant amount of the time of that is DB time, which is again our most in-demand resource. CPU/Memory is (generally) under-utilized on web apps and letting the EF do it's lazy loading thing is usually the best solution. As for explicit lazy loading, it's inelegant and way more code. One thing we know for sure, more lines = more bugs. I'm not saying turning off LL is a bad thing, if it works for you, but I semi-regularly have a SQL profiler running while developing so I see when it starts kicking out loads of queries un-necessarily.