﻿<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Ayende @ Rahien</title><link>http://ayende.com</link><description>Ayende @ Rahien</description><copyright>Copyright (C) Ayende Rahien  2004 - 2021 (c) 2026</copyright><ttl>60</ttl><item><title>Mike Brown commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Other than the needless sort (not sure why that's there) and the compute scalars (which are negligible in the query plan) the EF and NH query plans are equivalent.
  
  
Someone's already mentioned that a true head to head match would be NQL vs ESQL (or Linq to NHibernate vs Linq to Entities) right now you're comparing apples to oranges.
  
  
Also, without a large dataset and database optimization (indices where they need to be). The query plan tells you nothing. That sort accounts for 47% of the operation, but if the total execution time is under 5 milliseconds for 10k rows who cares? The database isn't your bottleneck in that case, the network will be.
  
  
Everything needs to be considered in context. The benefit of EF and NH is that you don't have to worry about these things until they become a problem. If you're noticing response issues, that's when you pop open EFProf/NHProf (or the built in SQL Profiler for SQL Server) and look what's going on. Heck SQL Server even comes with an analysis tool that will recommend ways to improve the performance of the database from your usage. Make your load tests, run it against your database with the analysis tool on and look at the results.
  
  
Finally, after looking at all of these, if I still see a problem, I have the option of wrapping that call in a sproc with EF or NH.
  
  
It's a good thing that you're providing these tools for devs to understand what's going on behind the scenes. But without a skilled DBA who can provide true guidance on whether that should give pause, or if it's a code or Database concern it's like having an MRI and no Doctor to read it.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment28</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment28</guid><pubDate>Tue, 30 Mar 2010 23:55:34 GMT</pubDate></item><item><title>Greg Law commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>I agree with Alex for the most part. My initial reaction was to gawk at the number of clustered index scans (e.g. table scans) in each of the query plans. Perhaps this is somewhat of a misnomer in this case if there isn't much data in the tables or a lack of indexes, though.
  
  
Tossing that aside for the moment, it does seem LINQ to SQL is the worst case of the three and I don't understand why it needs COUNT(*) from Comments. I may be mistaken (I haven't peeked at the internal LINQ to SQL code), but this could probably be removed and handled more efficiently on the client side.
  
  
As far as the amount of data passed across the network, LINQ to SQL is probably somewhat more efficient. NHibernate and Entity Frameworks isn't exactly returning a Cartesian product, but it's close enough I think I understand why you say it is.
  
  
Just curious here, but have hierarchical resultsets fallen out of favor? I haven't dealt with them in years and have one VB6 project using them that I need to rewrite in C# at some point.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment27</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment27</guid><pubDate>Fri, 05 Feb 2010 20:55:03 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Sorry, "One more evidence: IF estimated amounts"...
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment26</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment26</guid><pubDate>Fri, 05 Feb 2010 18:29:12 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>&gt; Based on the costs in the query plan I'm guessing there is virtually no data in the test database
  
  
Most likely. One more evidence: estimated amounts of data are large, there must be hash or merge join instead of nested loops.
  
  
&gt; What happens when there is significantly more data loaded?
  
+1.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment25</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment25</guid><pubDate>Fri, 05 Feb 2010 18:28:05 GMT</pubDate></item><item><title>tobi commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>John Chapman is right but in case of EF you can see clearly that it is inferior to the other two. The SQL is ridiculous.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment24</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment24</guid><pubDate>Fri, 05 Feb 2010 16:05:57 GMT</pubDate></item><item><title>John Chapman commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Based on the costs in the query plan I'm guessing there is virtually no data in the test database?  How else would a clustered index seek and a clustered index scan (on what should be a single item in the nested loop) have the same cost?
  
  
What happens when there is significantly more data loaded?
  
  
My initial thought was the question the database design, but now I'm more concerned about the sample data size and discussing optimization on such a small data set that it would really never matter.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment23</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment23</guid><pubDate>Fri, 05 Feb 2010 14:10:24 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Until there are 2 index scans and 2 nested loop joins, I''m not sure if there are any reasons for optimizing SQL here. I.e. indexes and properly defined foreign key constraints must be established first.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment22</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment22</guid><pubDate>Fri, 05 Feb 2010 08:42:55 GMT</pubDate></item><item><title>Frank commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>You could do a transformation (in the query convert to a DTO containing all the information you want). That way, you don't have to think about eager and lazy loading, for display purposes.
  
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment21</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment21</guid><pubDate>Fri, 05 Feb 2010 07:29:03 GMT</pubDate></item><item><title>Dmitry commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>One thing that I find problematic in NHibernate is doing server-side paging while eager-loading many-to-one associations. DistinctEntityRoot transformer operates in memory so you will end with less items per page than expected.
  
  
It looks like the options are using batch loading instead of eager loading or having a subquery that returns distinct ids. Is there a more elegant way of doing this?
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment20</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment20</guid><pubDate>Fri, 05 Feb 2010 05:39:54 GMT</pubDate></item><item><title>NC commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>What would the execution plan be if you were to do say (with LINQ to SQL)
  
  
var result = from p in ctx.Posts
  
                     join c in ctx.Comments
  
                     on p.PostID equals c.PostID
  
                     where p.PostID = 1
  
                     select new Post()
  
                     {
  
                            PostID = p.PostID,
  
                            Comments = c.PostComments.ToList(),
  
                            .....
  
                     };
  
  
Because you would be doing a join, and not two seperate queries.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment19</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment19</guid><pubDate>Thu, 04 Feb 2010 23:05:56 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>&gt; Btw, I'd like to see the same, but this appropriate indexes.
  
  
Or more data, if they are there. SQL Server might really prefer scan, if there are just few hundreds of records in Posts and Comments tables (i.e. very few pages).
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment18</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment18</guid><pubDate>Thu, 04 Feb 2010 19:41:52 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Too many mistypings again ;)
  
  
&gt; intrinsically dependent on NH on EF
  
" NH or EF"
  
  
&gt; but this appropriate indexes
  
"with appropriate ..."
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment17</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment17</guid><pubDate>Thu, 04 Feb 2010 19:39:28 GMT</pubDate></item><item><title>Alex Yakunin commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>May be I'm wrong, bot all the cases seems nearly equally bad for me:
  
  
1. The only index seek operation there happens for PK_Blogs. Other indexes, that are normally quite large, are scanned. May be this is acceptable in exactly your case (SQL Server makes such decision based on statistics), but in general, this is quite bad. Are there any indexes allowing to do this better at all? E.g. I'd create indexes for Post.Blog and Comment.Post properties.
  
  
2. L2S plan seems the strangest one. It scans 3 indexes. Why? Because it computes count(*) aggregate, that actually isn't really necessary in your case (count of items in the collection can be computed completely on the client).
  
  
3. EF and NH plans are very similar, the only difference is in sequence of nested loop joins -  in NH case it is much better (potential number of rows @ left &amp; right side in both nested loops must be much lower). But this isn't something that is intrinsically dependent on NH on EF - it's just the result of SQL Server query optimizer work. I.e. in your particular case (data, I mean) the second plan might really look more attractive for it.
  
  
Btw, I'd like to see the same, but this appropriate indexes. There is nothing to compare without them - i.e. SQL Server already did the best while decided to make a single index seek at least ;) 
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment16</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment16</guid><pubDate>Thu, 04 Feb 2010 19:36:39 GMT</pubDate></item><item><title>Ayende Rahien commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Damien,
  
I just tested that with EF 4.0
  
The queries are basically the same, the only difference in the aliases used.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment15</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment15</guid><pubDate>Thu, 04 Feb 2010 17:17:44 GMT</pubDate></item><item><title>Ayende Rahien commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Damien,
  
It is 3.5, I'll post about the difference between 3.5 &amp; 4.0 shortly
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment14</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment14</guid><pubDate>Thu, 04 Feb 2010 16:59:09 GMT</pubDate></item><item><title>Matt commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>I *think* this is EFv1. Assuming I have that correct, I would be interested to see the same SQL and query plan with EFv4 when it is finally released.
  
  
As much as I want EF to have the favourable SQL and query plan my gut reaction is to shy away from anything that is more complicated than it needs to be.
  
  
There is an argument to say "it's a tool, don't worry about it" but sooner or later you will need to and having something nicely formatted and concise to wade through will be easier!
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment13</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment13</guid><pubDate>Thu, 04 Feb 2010 16:49:28 GMT</pubDate></item><item><title>Damien Guard commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>What version of Entity Framework is being used here - 3.5SP1 or 4.0?  There was a lot of query optimization work done in 4.0.
  
  
[blogs.msdn.com/.../...ed-sql-in-net-4-0-beta1.aspx](http://blogs.msdn.com/adonet/archive/2009/08/05/improvements-to-the-generated-sql-in-net-4-0-beta1.aspx)  
  
[)amien
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment12</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment12</guid><pubDate>Thu, 04 Feb 2010 16:49:05 GMT</pubDate></item><item><title>Jimmy Chan commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>So Ayende, which is better?
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment11</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment11</guid><pubDate>Thu, 04 Feb 2010 16:45:25 GMT</pubDate></item><item><title>Graeme Hill commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>LINQ to SQL is not very good at eager loading one-to-many associations.  It often generates multiple queries or even select n+1 scenarios.
  
  
The output of the NHibernate sample is exactly what I would expect.  Why does it need to be any more complicated?
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment10</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment10</guid><pubDate>Thu, 04 Feb 2010 16:38:23 GMT</pubDate></item><item><title>Mischa Kroon commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>I'm really looking forward to some examples of there the new EF4 query output. 
  
  
Just curious if it will be a bit nicer to look at. 
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment9</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment9</guid><pubDate>Thu, 04 Feb 2010 16:38:04 GMT</pubDate></item><item><title>Nick Berardi commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>It would be interesting to see what the equivalent ESQL comes up with, because I don't really trust the LINQ to produce a good equivalent given the history of the late addition of LINQ to the entity framework by the ADO.NET team. 
  
  
SELECT VALUE 
  
    b
  
FROM 
  
    BlogEntities.Blogs AS b
  
    OUTER APPLY b.Posts AS p
  
    OUTER APPLY p.Comments AS c
  
WHERE
  
    b.Id = @Id
  
  
I usually like to try the similar in ESQL, because of the rushed nature of LINQ in EF 1.0.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment8</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment8</guid><pubDate>Thu, 04 Feb 2010 16:36:47 GMT</pubDate></item><item><title>Mike commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Curious what the logic i/o count is for the three?
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment7</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment7</guid><pubDate>Thu, 04 Feb 2010 16:35:22 GMT</pubDate></item><item><title>tobi commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>In a previous post of Ayende I have seen Entity Framework use a UNION ALL which is superior to any of the above approaches. I wonder
  
  
a) if NHibernate will support it in the future
  
b) why EF sometimes chooses to do such a bad job as it did in the example above
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment6</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment6</guid><pubDate>Thu, 04 Feb 2010 15:18:25 GMT</pubDate></item><item><title>Matt Hidinger commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>Was this SQL generated from EF1 or EF4? 
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment5</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment5</guid><pubDate>Thu, 04 Feb 2010 15:16:38 GMT</pubDate></item><item><title>J commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>....which is why i just write the SQL I want in the first place...
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment4</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment4</guid><pubDate>Thu, 04 Feb 2010 14:37:11 GMT</pubDate></item><item><title>Carsten Hess commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>I second Henning - Cartesian product is tableA x tableB without restricting join or where clauses. 
  
  
In all of the 3 cases you need 1 blog and its associated posts and their associated comments.
  
  
For me the difference is that in the NHibernate case you get your Blog-entity redundantly back for every row returned. In the Linq-to-SQL you only get it once. So its more a matter of getting superfluous data from the database to the application (which can also important be important based on amount of rows and data in Blog ofcourse).  
  
  
Both solutions are still getting superfluous data for the Posts (when more than one Comment per Post exists).    
  
  
On the downside for the Linq-to-sql SQL there is the Count aggregation which takes around 31% in total (Rightmost scan of Comments in executionplan). This aggregation is completely missing  (not necessary) in NHibernate.
  
  
Concerning EF, the query is pretty much identical to the one from NHibernate, apart from the expensive sorting (which is also the reason for the case logic - that prevents sorting on null's). Why they find it necessary to do the "outer" select I don't know - but could imagine is has to do with the way the SQL is constructed from the expression tree.
  
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment3</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment3</guid><pubDate>Thu, 04 Feb 2010 12:07:01 GMT</pubDate></item><item><title>Rafal commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>The execution plans are very similar in each case, so the query performance should be roughly the same.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment2</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment2</guid><pubDate>Thu, 04 Feb 2010 11:38:21 GMT</pubDate></item><item><title>Henning commented on What happens behind the scenes: NHibernate, Linq to SQL, Entity Framework scenario analysis</title><description>hmm - maybe I'm missing out on something, but in which case does the NH approache create a cartesian product?
  
  
As far as I know a cartesian product means to take all blogs, posts and comments and create a "matrix" of all possible combinations of blogs, posts and comments.
</description><link>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment1</link><guid>http://ayende.com/4387/what-happens-behind-the-scenes-nhibernate-linq-to-sql-entity-framework-scenario-analysis#comment1</guid><pubDate>Thu, 04 Feb 2010 11:25:02 GMT</pubDate></item></channel></rss>